适用版本
OceanBase 数据库 V4.0 之前的版本。
问题描述
OceanBase 数据库 Oracle 模式插入语句。
insert into "t3"( "ID", "CODE", "STEP") values(:0,:1,:3)
报锁冲突错误,具体错误如下。
ORA-00600: internal error code, arguments: -6005, Try lock row conflict
问题原因
与外键多重关联有关:可以看到表 2、表 3 都与表 1 有外键关联,同时表 3 与表 2 又有外键关联。具体表结构如下。
-- 表1
CREATETABLE"t1"(
"CODE"NUMBER(3) NOT NULL ENABLE,
"NAME"VARCHAR2(50 BYTE),
CONSTRAINT"pk_T1"PRIMARY KEY("CODE")
)COMPRESS FOR ARCHIVER EPLICA_NUM=3BLOCK_SIZE=16384 USE_BLOOM_FILTER=FALSE
TABLET_SIZE=134217728 PCTFREE=0;
-- 表2,:
CREATETABLE"t2"(
"STEP"NUMBER(3) NOT NULL ENABLE,
"CODE"NUMBER(3),
PRIMARY KEY("STEP"),
CONSTRAINT"Fk1" FOREIGN KEY("CODE")REFERENCES "t1"("CODE"),
)COMPRESS FORA RCHIVE REPLICA_NUM=3 BLOCK_SIZE=16384 USE_BLOOM_FILTER=FALSE
TABLET_SIZE=134217728 PCTFREE=0;
-- 表3,:
CREATETABLE"t3"(
"ID"NUMBER(10) NOT NULL ENABLE,
"CODE"NUMBER(3) NOT NULL ENABLE,
"STEP"NUMBER(3) NOT NULL ENABLE,
CONSTRAINT"pk_t3" PRIMARY KEY("ID"),
CONSTRAINT"fk23"FOREIGN KEY("CODE")REFERENCES
"t1"("CODE"),
CONSTRAINT"fK32" FOREIGN KEY("STEP")REFERENCES
"t2"("STEP")
)COMPRESS FOR ARCHIVE REPLICA_NUM=3 BLOCK_SIZE=16384 USE_BLOOM_FILTER=FALSE
TABLET_SIZE=134217728 PCTFREE=0;
最终原因是 Foreign key 约束父表冲突问题。
在子表中插入数据时,在验证父表中外键是否存在时会给外键的行上加行锁,来避免 Write Skew 产生。这样做产生的直接问题是在子表中同时插入引用相同外键的行会在父表上产生严重的锁冲突,导致子表更新有严重的性能问题。
解决方法
删除外健约束,改为 check 约束。
obclient> alter table t2 drop constraint Fk1;
obclient> alter table t3 drop CONSTRAINT fk23;
obclient> alter table t3 drop CONSTRAINT fk32;
obclient> alter table t2 add constraint check_code1_t2 check(CODE in(1,2,3));
obclient> alter table t3 add constraint check_code1_t3 check(CODE in(1,2,3));
obclient> alter table t3 add constraint check_step check(STEP in(1,2,3));