626错误发生的场景与原因:
1.可重现场景:
A.创建分片表
create table test_fragtable_serial
(
t1 serial not null ,
t2 integer,
t3 char(200)
)fragment by expression
((t2 >= 100000 ) AND (t2 < 200000 ) ) in dbs12,
((t2 >= 300000 ) AND (t2 < 400000 ) ) in dbs14,
((t2 < 300000 ) AND (t2 >= 200000 ) ) in dbs13,
((t2 < 100000 ) AND (t2 >= 1 ) ) in dbs11;
create index idx_test_fragtable_serial_1 on test_fragtable_serial (t1) using btree ;
create index idx_test_fragtable_serial_2 on test_fragtable_serial (t2) using btree ;
B.Session 1
读取表test_fragtable_serial的数据,可以设置不同的隔离级别;
begin work;
set isolation to dirty read;
--set isolation to repeatable read;
--set isolation to committed read;
SET ISOLATION TO COMMITTED READ LAST COMMITTED;
select t1.t1,t2.t1,t3.t1,t4.t1 from test_fragtable_serial t1,test_fragtable_serial t2,test_fragtable_serial t3,test_fragtable_serial t4;
--session 2 执行时尚未提交
commit work;
C.Session 2
begin work;
lock table test_fragtable_serial in exclusive mode;
alter fragment on table test_fragtable_serial detach dbs11 tmp_statistics33;
drop table tmp_statistics33;
commit;
D.当session 2 执行lock table语句后,如果同时有另外的的一个并发访问表test_fragtable_serial的session正在执行,此时session 1根据不同的isolation级别将报告不同的错误。
而同时,session 2 执行后续的alter fragment语句将报告626的错误,该错误同时提示106错误,由于表test_fragtable_serial正在被访问从而导致626错误。
2.错误发生原因分析:
使用Exclusive Lock并发访问表产生的错误。
当在一个表上成功执行LOCK TABLE tabname in exclusive mode 语句后,其他用户不能在该表上获得锁。
当你尝试在该表上执行一个DDL操作语句,如果该表正在被另外一个并发的session访问(比如通过游标方式) 你可能收到一个RSAM错误-106。
这个错误同时也会影响特定的DDL语句自动加在该表上的锁。
这种情况是可能发生的,由于表的锁不能阻止表被访问。一个exclusive锁可以防止其他用户在该表上获取一个锁,但是它不能防止其他用户打开一个表等待exclusive锁释放后进行写操作,或者在该表上进行隔离级别为dirty read的读操作。
你可以通过设置IFX_DIRTY_WAIT环境变量来定义一个DDL操作等待其他脏读操作提交的时长。
3.解决方案
当遇到类似的错误时,我们可以采用其他途径来解决问题。
如上面描述的对表进行分片维护时的情况,我们可以通过尝试多次的方法来解决该问题,通常情况建议采用一个字典表来记录表分片的情况,通过读取该记录表来判定表是否需要进行分片维护,通过多次尝试的办法可以避免由于某些时刻表
被并发访问的情况从而导致的分片操作失败的情况;
另外,我们应该合理的利用隔离级别来进来避免锁的冲突和死锁问题,提供系统的并发处理能力。