首批通过分布式安全可靠测评,为关键业务系统打造
XA 事务和悬挂事务诊断
更新时间:2026-04-14 11:55:54
本文介绍了 OceanBase 数据库事务的诊断方式。
基本介绍
OceanBase 数据库的事务按照参与者的个数和位置可以分为三种类型:普通事务、分布式事务、XA 事务;普通事务、分布式事务又可以统称为非 XA 事务。 而事务按照执行的时间和状态可以分为其他事务、长事务、悬挂事务三种。其中,长事务和悬挂事务会导致资源长时间不释放,等待会话长时间被阻塞,影响业务系统。 在日常工作中,需要重点关注这类异常的事务。接下来对这类事务分别进行介绍。
说明
当 OceanBase 为 V4.0 及以上版本时,暂不支持 XA 事务类型。
场景描述
长事务
长事务指那些长时间未提交的事务。普通事务、分布式事务、XA 事务都可能处于长事务的状态。当普通事务、分布式事务处于长事务状态时,可以通过 kill session 的方式来回滚事务;当 XA 事务处于长事务状态时可以终止 XA 事务。
长事务产生的原因可能是事务中的某条 SQL 执行时间较长,或执行完 SQL 后长时间未完成提交或回滚。如果当前的长事务对系统造成了资源阻塞,可以通过回滚普通长事务会话或终止 XA 事务进行处理。
使用命令行进行会话管理
说明
以下代码示例除非特别说明外,默认使用 sys 租户。
查看数据库里是否存在长事务。
SELECT * FROM OCEANBASE.__all_virtual_trans_stat WHERE part_trans_action <= 2 AND ctx_create_time < date_sub(now(), INTERVAL 600 SECOND) AND is_exiting != 1查看事务是否为 XA 事务,其中事务 ID 为上述 sql 中查出的
svr_ip。如果sql执行结果为空,则表明长事务非XA事务;如果执行有结果,则对应的结果即为 XA 事务。SELECT * FROM OCEANBASE.__all_virtual_global_transaction WHERE trans_id LIKE '%事务ID%';处理长事务,请执行下列命令。
回滚普通长事务。注意,kill 会话需要直连对应的 OBServer 节点,无需通过 proxy 连接数据库。
SELECT svr_ip FROM OCEANBASE.__all_virtual_processlist WHERE id=会话ID; kill 会话ID;终止 XA 事务,请执行下列命令。
前往系统租户,查找 XA 事务的 XID。
SELECT hex(gtrid),hex(bqual),format_id FROM OCEANBASE.__all_virtual_global_transaction WHERE tenant_id = 租户ID AND format_id <> -2 AND state = 3 AND gmt_modified < date_sub(now(), INTERVAL 1800 SECOND);如果是 Oracle 模式租户,可以前往普通租户查看 XA 事务的 XID。
SELECT rawtohex(gtrid),rawtohex(bqual),format_id FROM sys.all_virtual_tenant_global_transaction_agent WHERE format_id <> -2 AND state = 3 AND ROUND((sysdate - cast(GMT_MODIFIED as date)) * 86400) > 1800;前往普通租户执行,终止 XA 事务。
set serveroutput on; declare l_xid DBMS_XA_XID; l_ret PLS_INTEGER; BEGIN l_xid.formatid := format_id; l_xid.gtrid := hextoraw('hex(gtrid)'); l_xid.bqual := hextoraw('hex(bqual)'); l_ret := DBMS_XA.XA_ROLLBACK(xid = > l_xid); dbms_output.put_line(l_ret); END; /
悬挂事务
悬挂事务指提交后,长时间没有结束的事务。常见的场景,有两种情况:
事务涉及的分区无主,导致事务状态机推进不了;
事务在 leader 上已经推进完成,但由于备机的内存、网络带宽等资源限制,日志同步慢、回放慢,导致事务状态结束慢。
上述两种场景,处理方法是不一样的,下文分别描述。
分区无主
OceanBase 数据库的架构决定分区是有多副本的,多副本中只有一个 leader (主),其它都是 follower (从)。而当 leader 所在 OBsever 宕机了,此时就没有了 leader,少数派副本异常情况下,此时其它副本就会根据 PAXOS 协议重新选主,在此过程中正在运行的事务有可能就产生长事务。
对于这种场景,使用如下方式进行处理:
查询当前事务涉及的所有的表信息,SQL 如下,其中
participants里的每个tid代表一个表。SELECT svr_ip, trans_id, participants FROM OCEANBASE.__all_virtual_trans_stat WHERE part_trans_action> 2 AND ctx_create_time < date_sub(now(), INTERVAL 600 SECOND) AND is_exiting != 1;分别确认上述分区列表是否有主,SQL 如下,若
role列皆为 follower,则表示全部是从副本,没有 leader。SELECT svr_ip, svr_port,table_id, partition_idx, role, status, replica_type FROM OCEANBASE.__all_virtual_clog_stat WHERE table_id=表ID;若为分区无主即当前事务为长事务,可按照长事务进行处理。
副本应用日志慢
副本应用日志慢的原因有很多。比如某个 OBServer 节点服务器突然资源异常,OS 上跑任务消耗了大量的 IO、网络等资源,导致该服务器上的 OBSever 响应慢;主副本分布不均匀,某服务器上的 leader 特别多,leader 进行应用需求响应,消耗大量资源,导致 follower 的可用资源比较少,从而一直追不上该 follower 对应的 leader;某个 OBserver 节点服务器硬件异常,比如网卡异常,导致 PAXOS 协议传到 follower 非常慢,一直处于等待中,追赶中;该 OBSever 正在合并或备份中等。
对于这种场景,使用如下方式进行处理:
查询当前事务涉及的所有的表信息,SQL 如下,其中
partition里的每个tid代表一个表。SELECT svr_ip, svr_port,trans_id, 'partition' FROM OCEANBASE.__all_virtual_trans_stat WHERE part_trans_action > 2 AND ctx_create_time < date_sub(now(), INTERVAL 600 SECOND) AND is_exiting != 1;根据第一步查询到的
partition中记录的table_id信息,确认当前pkey对应的leader位置。SELECT svr_ip,svr_port FROM OCEANBASE.__all_virtual_clog_stat WHERE role='LEADER' AND table_id = 表ID;如果第一步和第二步对应的
svr_ip不同,说明异常事务在 follower 上存在。查询上述事务对应的分区,目前集群中的记录条数。
SELECT count(1) FROM OCEANBASE.__all_virtual_trans_stat WHERE trans_id LIKE '%{选取第一步 trans_id 中的 hash 字段}%'AND`partition` LIKE '%xxx%';如果上述查询结果为 1 条,说明只有备机上存在。这种情况请联系OceanBase 技术支持团队处理。