环境:
AWS 亚马逊云 oracle 19c
问题说明:
生产上进行数据删除(进行大表的列删除),删除后报警日志一直有报错:ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln], [49]
删除的语句为:
alter table user_order_detail set unused (DEL_IND,DEL_USER_ID,DEL_DTT) online;
alter table user_order_detail drop unused columns checkpoint 1000;
其实有几个aws 执行了删除语句,没有报错;但是有几个有报错。
问题排查:
1.排查业务是否有问题
虽然都知道ORA-600是数据库的内部问题引起的报错,但是,其中有的oracle数据库有报错,有的没有报错,所以最初怀疑是由于业务引起的表结构变化了,业务代码没有变化,导致的数据库不识别业务代码抛出报错;
后经过业务开发人员的排查,没有问题,所以还是怀疑是数据库内部方面问题。
2.排查数据库的问题
查看alert日志详细信息:
ORA-00600: internal error code, arguments: [insChkBuffering_1], [4], [4], [], [], [], [], [], [], [], [], []
查看类似相关很多的trc文件:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.8.0.0.0
Build label: RDBMS_19.8.0.0.0DBRU_LINUX.X64_200702
ORACLE_HOME: /rdsdbbin/oracle
System name: Linux
Node name:
Release: 4.1.12-124.28.6.el7uek.x86_64
Version: #2 SMP Tue Jun 25 20:08:29 PDT 2019
Machine: x86_64
VM name: Xen Version: 4.11 (HVM)
Instance name: CLDTTFC
Redo thread mounted by this instance: 1
Oracle process number: 1456
Unix process pid: 28607, image: oracle
*** 2021-09-16T20:10:29.643785+08:00
*** SESSION ID:(15042.34599) 2021-09-16T20:10:29.643812+08:00
*** CLIENT ID:() 2021-09-16T20:10:29.643845+08:00
*** SERVICE NAME:(SYS$USERS) 2021-09-16T20:10:29.643853+08:00
*** MODULE NAME:(dotnet.exe) 2021-09-16T20:10:29.643861+08:00
*** ACTION NAME:() 2021-09-16T20:10:29.643868+08:00
*** CLIENT DRIVER:(ODPC.NET : 18.3.0.0.0) 2021-09-16T20:10:29.643914+08:00
2021-09-16T20:10:29.643530+08:00
Incident 2411672 created, dump file: /rdsdbdata/log/diag/rdbms/cldttfc_a/CLDTTFC/incident/incdir_2411672/CLDTTFC_ora_28607_i2411672.trc
ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln], [49], [], [], [], [], [], [], [], [], [], []
2021-09-16T21:27:20.089785+08:00
Incident 2411673 created, dump file: /rdsdbdata/log/diag/rdbms/cldttfc_a/CLDTTFC/incident/incdir_2411673/CLDTTFC_ora_28607_i2411673.trc
*** 2021-09-16T21:27:20.089915+08:00
ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln], [49], [], [], [], [], [], [], [], [], [], []
2021-09-17T07:16:29.448634+08:00
Incident 2411674 created, dump file: /rdsdbdata/log/diag/rdbms/cldttfc_a/CLDTTFC/incident/incdir_2411674/CLDTTFC_ora_28607_i2411674.trc
*** 2021-09-17T07:16:29.448742+08:00
ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln], [49], [], [], [], [], [], [], [], [], [], []
2021-09-17T09:26:38.390214+08:00
Incident 2411675 created, dump file: /rdsdbdata/log/diag/rdbms/cldttfc_a/CLDTTFC/incident/incdir_2411675/CLDTTFC_ora_28607_i2411675.trc
*** 2021-09-17T09:26:38.390317+08:00
ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln], [49], [], [], [], [], [], [], [], [], [], []
如此的信息也是头疼,aws查询没有CLDTTFC_ora_28607_i2411675.trc这种的类似文件。
2.1 support 关键字搜索
利用关键字ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln], [49] 搜索到一系列不太相关的解决办法,需要把
alter system set "_ignore_fg_deps"=ALL;
但是相关的BUG都是12c以及之前的版本,没有涉及到19c,不太靠谱。
2.2 Bug 30404639 (support Doc ID 30404639.8)
后面通过相关业务某些语句不能执行,发现不能执行的语句为包含触发器相关的业务。所以找到是由于drop unused column引起的原因触发器不正常。
- 21.1.0.0.0
- 19.10.0.0.210119 (Jan 2021) Database Release Update (DB RU)
- 18.14.0.0.210420 (APR 2021) Database Release Update (DB RU)
这三个版本的以前大版本都有此BUG,之后都已修复。
删除具有触发器的表中的列可能会导致如果触发器使用的列引用了不正确的触发器操作 :NEW/:OLD。 如果触发器在之后停止正常工作,可能会看到此问题该表已删除一列,触发器使用:OLD或:NEW。请看support下面例子操作(非sys用户)
下面由于是19.3 稍加修改了一下脚本,support上的是18.3,删除列后没有truncate table t2,
脚本来自:https://jonathanlewis.wordpress.com/2020/01/14/drop-column-bug/
create table t1 (c0 varchar2(30), c1 varchar2(30), c2 varchar2(30), c3 varchar2(30), c4 varchar2(30));
create table t2 (c_log varchar2(30));
create or replace trigger t1_ariu
after insert or update on t1
for each row
begin
IF :new.c3 is not null then
insert into t2 values (:new.c3);
end if;
end;
/
insert into t1(c3) values ('Inserting c3 - should log');
select * from t2;
insert into t1(c4) values ('Inserting c4 - should not log');
select * from t2;
现在,当 T1.C2 列被删除时,我们希望触发器失效并重新编译以再次工作。然而,无效发生,并且触发器以意想不到的方式工作。
alter table t1 set unused (c1, c2);
alter table t1 drop unused columns;
truncate table t2;
insert into t1(c3) values ('Inserting c3 - should log');
select * from t2;
insert into t1(c4) values ('Inserting c4 - should not log');
select * from t2;
触发器似乎“丢失了表中列的计数”(大概它被编译为引用类似“column_position = 3”的东西,并且不会在“drop column”上进行调整——MOS 上的链接错误注释指的是这个问题与项目相关联以增加细粒度的依赖关系)所以它设法在删除一列的情况下存活下来,因为仍然有一个“第 3 列”,现在恰好是曾经是“第 4 列”的列。
解决方法
如果在生产oracle数据库删除大表的列后,报错ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln],这个只会使用两步法删除列,即:先设置未使用,然后再删除。如果只是发出“alter table t1 drop column c1”(带有或不带有“checkpoint NNN”),则不会出现问题。删除表中出现在触发器中提到的最高位置列之前的列。因为列出现在表声明中的顺序不一定是内部列顺序。
解决方法:
1.“alter trigger t1_ariu compile”;
2.或者进行触发器的删除后重建。
指定COMPILE
显式编译触发器,无论它是有效还是无效。显式重新编译消除了对隐式运行时重新编译的需要,并防止了相关的运行时编译错误和性能开销。