最近两个项目都是使用OceanBase3.2.3,业务租户主要是For Oracle,主要工作是从老业务系统迁移数据到新业务系统,在使用过程中遇到了几点问题以及规避的思路:
场景一:大事务拆分
OcenBase在并行处理多个大事务的时候,会有产生ERROR-06002 Transaction rollbaced或者ORA-24761 transaction context does not exists的错误,通过排查日志发现是insert的时候发现了switch leader操作,日志中,报了ret=-4038,然后切主是由参数clog_sliding_window_timeout控制的,不知道怎么解决只能把大事务进行拆分。
修改前示例如下:其中A、B两表的数据量都在8000万左右,
insert into table_a (.....) select ..... from A join B on A.column_a=B.column_a
避免这个错误的方式就是把事务缩小,我们在缩小事务的时候使用了分区裁剪的方式。两个表都按照关联字段创建hash分区,然后都属于同一个表组
create tablegroup a_and_b partition by hash partitions 32;
create table A (....) tablegroup = "a_and_b" partition by hash (column_a) partitions 32;
create table B (....) tablegroup = "a_and_b" partition by hash (column_a) partitions 32;
修改后的sql加工语句
insert into table_a (.....) select ..... from A partition(p0,p1,p2,p3) join B partition(p0,p1,p2,p3) on A.column_a=B.column_a
--以此类推,最后到分区p31
场景二:合理的利用hint
1、parallel(n),提高并行度的hint
insert into table_a (.....) select /*+paraller(8)*/ ..... from A join B on A.column_a=B.column_a
这个n是通过参数parallel_max_servers控制,所以并行执行的n之和,尽量不要大于parallel_max_servers的值,否则也不会生效,还可能出现意想不到的问题。
2、弱一致读READ_CONSISTENCY(WEAK)
insert into table_a (.....) select /*+paraller(8) READ_CONSISTENCY(WEAK)*/ ..... from A join B on A.column_a=B.column_a
弱一致读是尽可能消除了分布式执行计划,但是某种程度上也消除了分布式处理数据的能力,使用时需要进行取舍。
3、数据导入的并行dml
insert /*+ENABLE_PARALLEL_DML paraller(8)*/ into table_a (.....) select ..... from A join B on A.column_a=B.column_a
append旁路导入hint在OB4.x以后的版本才支持
insert /*+APPEND ENABLE_PARALLEL_DML paraller(8)*/ into table_a (.....) select ..... from A join B on A.column_a=B.column_a
场景三:truncate操作超时
truncate操作在OB里是写死在代码里的好像是20多s,集群在比较繁忙的时候执行truncate可能会导致4012错误,繁忙期间尽量避免truncate操作,或者进行重试。
场景四:obdumper超时
在对一个表进行大量数据插入,在收到返回提交成功以后,紧接着对该表执行obdumper操作,可能会收到错误Dump failed:Error:ORA-02409:timeout:distributed transaction waiting for lock。
这个问题主要是commit执行二阶段提交,虽然服务器返回成功,但是后台还在执行commit操作,因此建议对表执行大批量操作以后,延迟一会在进行数据导出操作。
场景四:大事务中避免使用函数
这个问题没有详细的进行跟踪,猜测还是主要由于sub plan计划导致的。所以尽量要避免使用函数或子查询,尽量使用join对表进行操作。
场景五:obdumper/obloader导致进程宕掉
obdumper/obloader默认是启动一个4G的jvm虚拟机,如果要批量进行加载或者卸载的时候一定要计算宿主机的内存,避免产生数据不一致的问题。也一定要捕获obloader和obdumper的执行结果,避免数据不一致,因为obloader在进程宕掉以后,数据是不会进行回滚的,可以参考一下如下代码:
obloader -H ......... if [ $? -ne 0 ];then echo "obloader error" exit 1 fi
暂时就写这么写,后续在持续进行补充吧。




