为什么Oracle在提交期间丢失数据?

GIS*_*han 6 oracle oracle10g

我有一个相当标准的SQL查询,如下所示:

TRUNCATE TABLE TABLE_NAME;
INSERT INTO TABLE_NAME 
(
UPRN,
SAO_START_NUMBER,
SAO_START_SUFFIX,
SAO_END_NUMBER,
SAO_END_SUFFIX,
SAO_TEXT,
PAO_START_NUMBER,
PAO_START_SUFFIX,
PAO_END_NUMBER,
PAO_END_SUFFIX,
PAO_TEXT,
STREET_DESCRIPTOR,
TOWN_NAME,
POSTCODE,
XY_COORD,
EASTING,
NORTHING,
ADDRESS
)
SELECT  
BASIC_LAND_AND_PROPERTY_UNIT.UPRN, 
LAND_AND_PROPERTY_IDENTIFIER.SAO_START_NUMBER AS SAO_START_NUMBER, 
LAND_AND_PROPERTY_IDENTIFIER.SAO_START_SUFFIX AS SAO_START_SUFFIX, 
LAND_AND_PROPERTY_IDENTIFIER.SAO_END_NUMBER AS SAO_END_NUMBER, 
LAND_AND_PROPERTY_IDENTIFIER.SAO_END_SUFFIX AS SAO_END_SUFFIX, 
LAND_AND_PROPERTY_IDENTIFIER.SAO_TEXT AS SAO_TEXT, 
LAND_AND_PROPERTY_IDENTIFIER.PAO_START_NUMBER AS PAO_START_NUMBER, 
LAND_AND_PROPERTY_IDENTIFIER.PAO_START_SUFFIX AS PAO_START_SUFFIX, 
LAND_AND_PROPERTY_IDENTIFIER.PAO_END_NUMBER AS PAO_END_NUMBER, 
LAND_AND_PROPERTY_IDENTIFIER.PAO_END_SUFFIX AS PAO_END_SUFFIX, 
LAND_AND_PROPERTY_IDENTIFIER.PAO_TEXT AS PAO_TEXT, 
STREET_DESCRIPTOR.STREET_DESCRIPTOR AS STREET_DESCRIPTOR, 
STREET_DESCRIPTOR.TOWN_NAME AS TOWN_NAME, 
LAND_AND_PROPERTY_IDENTIFIER.POSTCODE AS POSTCODE, 
BASIC_LAND_AND_PROPERTY_UNIT.GEOMETRY AS XY_COORD, 
BASIC_LAND_AND_PROPERTY_UNIT.X_COORDINATE AS EASTING, 
BASIC_LAND_AND_PROPERTY_UNIT.Y_COORDINATE AS NORTHING,
decode(SAO_START_NUMBER,null,null,SAO_START_NUMBER||SAO_START_SUFFIX||' ')
||decode(SAO_END_NUMBER,null,null,SAO_END_NUMBER||SAO_END_SUFFIX||' ')
||decode(SAO_TEXT,null,null,SAO_TEXT||' ')
||decode(PAO_START_NUMBER,null,null,PAO_START_NUMBER||PAO_START_SUFFIX||' ')
||decode(PAO_END_NUMBER,null,null,PAO_END_NUMBER||PAO_END_SUFFIX||' ')
||decode(PAO_TEXT,null,null,'STREET RECORD',null,PAO_TEXT||' ')
||decode(STREET_DESCRIPTOR,null,null,STREET_DESCRIPTOR||' ')
||decode(POST_TOWN,null,null,POST_TOWN||' ')
||Decode(Postcode,Null,Null,Postcode)  As Address 
From (Land_And_Property_Identifier
      Inner Join Basic_Land_And_Property_Unit
        On Land_And_Property_Identifier.Uprn = Basic_Land_And_Property_Unit.Uprn)  
Inner Join Street_Descriptor
  On Land_And_Property_Identifier.Usrn = Street_Descriptor.Usrn
Where Land_And_Property_Identifier.Postally_Addressable='Y';
Run Code Online (Sandbox Code Playgroud)

如果我在SQL Developer中运行此查询,它运行正常,插入了180万个功能(select count(*) from TABLE_NAME在会话中确认了这一点).

但是当我运行提交时,数据就会消失!select count(*) from TABLE_NAME现在返回0结果.

我们已经做了很多尝试,看看发生了什么:

  • 在此期间Truncate,表空间被释放,并且在插入期间它再次被填充.提交期间没有变化.这意味着数据在数据库中.

  • 如果我执行完全相同的查询但and rownum < 100附加到结尾,则提交有效.与...相同1000.

  • 我发现了这个问题:oracle commit kill并让我们的DBA尝试"SQL Trace".这产生了一个> 4GB的文件,当用TKPROF解析时产生了120页的报告,但是我们不知道如何阅读它并且那里没有明显的错误.

  • 我们的错误日志中没有任何内容.并且在提交过程中显然没有错误.

  • 触发/序列在此过程中增加了180万.

我现在重复了大约4次,但结果总是一样的.

所以我的问题很简单 - 提交期间数据发生了什么?我们怎么知道?谢谢.

注意:这在过去运行良好,所以我不相信SQL本身有任何问题.


编辑:通过从头重新创建表来解决问题.现在,当我插入它时,与之前的2000相比只需要500秒.并且提交是即时的; 当它被打破时,提交需要4000秒!我仍然不知道为什么会这样.


对于那些询问,创建表语法:

CREATE TABLE TABLE_NAME
(
ADDRESS                                            VARCHAR2(4000),
UPRN                                               NUMBER(12),
SAO_START_NUMBER                                   NUMBER(4),
SAO_START_SUFFIX                                   VARCHAR2(1),
SAO_END_NUMBER                                     NUMBER(4),
SAO_END_SUFFIX                                     VARCHAR2(1),
SAO_TEXT                                           VARCHAR2(90),
PAO_START_NUMBER                                   NUMBER(4),
PAO_START_SUFFIX                                   VARCHAR2(1),
PAO_END_NUMBER                                     NUMBER(4),
PAO_END_SUFFIX                                     VARCHAR2(1),
PAO_TEXT                                           VARCHAR2(90),
STREET_DESCRIPTOR                                  VARCHAR2(100),
TOWN_NAME                                          VARCHAR2(30),
POSTCODE                                           VARCHAR2(8),
XY_COORD                                           MDSYS.SDO_GEOMETRY,
EASTING                                            NUMBER(7),
NORTHING                                           NUMBER(7)
)

CREATE INDEX TABLE_NAME_ADD_IDX ON TABLE_NAME (ADDRESS);
Run Code Online (Sandbox Code Playgroud)

Sus*_*tta -2

也许你有一个你没有注意到的触发器。你能检查一下oracle的回收站表,它可能存储着你删除的表和触发器的历史记录吗?

Select * from recyclebin;
Run Code Online (Sandbox Code Playgroud)

参考文献:http://www.oraclebin.com/2012/12/recyclebinflashback.html