问题现象
业务负载均衡、drop table、truncate table、drop replica 等几个操作,DB 端内部都会删除(GC)对应的分区。分区删除需要等事务结束,包括读写事务和只读事务。如果因为无主导致读写事务卡在两阶段提交流程、长只读事务因为种种原因不结束,此时 GC 会卡主。
报错日志如下。
transaction context not empty, try again
participant wait partition error
具体报错日志如下。
observer.log.20240112120343:[2024-01-**03:42.314633] WARN [STORAGE.TRANS] wait_partition (ob_trans_ctx_mgr.cpp:2579) [70417][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=10] [dc=0] transaction context not empty, try again(ctx_mgr=0x7f979a7ee9b0, partition={tid:1102810163215449, partition_id:0, part_cnt:0}, count=1, partition_type=2)
observer.log.20240112120343:[2024-01-**03:42.314681] WARN [STORAGE.TRANS] remove_partition (ob_trans_ctx_mgr.cpp:4022) [70417][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=29] [dc=0] participant wait partition error(ret=-4023, ret="OB_EAGAIN", retry=1021946, partition={tid:1102810163215449, partition_id:0, part_cnt:0}, *ctx_mgr={this:0x7f979a7ee9b0, partition:{tid:1102810163215449, partition_id:0, part_cnt:0}, state:5, ctx_type:2, read_only_count:1, active_read_write_count:0, total_ctx_count:1, restore_snapshot_version:-1, last_restore_log_id:18446744073709551615, last_restore_log_ts:-1, uref:1073741823})
关键诊断信息
触发条件
业务负载均衡、drop table、truncate table、drop replica 等几个操作,需要删除分区。分区删除需要等事务结束,包括读写事务和只读事务。无主导致读写事务卡在两阶段提交流程、长只读事务因为种种原因不结束,此时 GC 会卡住。
问题原因
一个长时间不结束的只读请求(因为 BUG 残留或者确实存在长只读事务),叠加分区 GC,会导致分区 GC 卡住。分区 GC 过程中,会在事务模块死循环检查事务是否结束,如果不结束,GC 线程会持有 PG、事务模块关于 partition 的锁,进而影响冻结、转储,最终可能导致 clog 盘爆。这个问题从 OceanBase 数据库 V2.x 版本一直以来都是如此的行为。
问题出现概率较低,但出现之后,问题比较严重,几个典型问题。
remove partition 卡住的问题,确认是卡在了存储迭代数据。
因为数据结构相关的 BUG,导致 SQL 执行卡在了
right_to_die方法上,只读语句无法结束。PX 执行因为活锁导致执行过程卡住(V4.x 问题,已经修复,但比较典型)。
远程执行的 SQL,kill 控制端,是 kill 不掉的。
问题的风险及影响
冻结卡住,内存爆。
由于无法转储,clog 无法回收,可能会爆。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
影响版本
OceanBase 数据库企业版 V2.2.77 GA(oceanbase-2.2.77-20210508211731)及之前版本、V3.1.2 GA(oceanbase-3.1.2-20210618150922)及之前版本、V3.2.3 GA(oceanbase-3.2.3.0-20220418212020)及之后版本、V3.2.4 GA(oceanbase-3.2.4.0-100000072022102819)及之前版本。
解决方法及规避方式
解决方法:
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库企业版 V3.2.3 BP11(oceanbase-3.2.3.3-111000032024070822)及之后版本、V3.2.4 BP8(oceanbase-3.2.4.8-108000142024041520)及之后版本
说明
- V3.2.4 BP8 版本和 V3.2.3 BP11 版本,已经对这个问题做了改进,事务不结束,超过 10 min 会报警 ERROR,需要人为介入处理,建议升级上述两个版本:分区 GC 会卡住,但不影响冻结转储、也不影响 clog 回收,运维人员介入之后,需要对出现问题的机器做 obstack、保留日志、重启进程等操作即可。
- kill session,如果不能恢复,需要 obstack 之后重启进程。
规避方式:
对执行时间比较长的只读请求做监控,这里只能从
__all_virtual_processlist中查询,活跃事务虚拟表中是没有记录的。查询待 GC 的分区,SQL 如下。
select count(1) from __all_virtual_partition_info where table_id in (select table_id from __all_virtual_table) and tenant_id = xxx;