集群CN故障导致两阶段提交有残留事务时,可以根据本节内容对这些残留事务进行修复。CN故障分为两种情形,情形1下故障CN可访问历史数据,情形2下故障CN无法访问历史数据。该操作仅支持分布式部署模式下执行。
背景信息
部署集群时,建议用户将CN实例分散部署在其他多个服务器上,以避免主机故障造成的集群不可用。如表1所示。
两阶段提交事务(2PC)的处理过程分为两个阶段:阶段1是PREPARE,阶段2是COMMIT。2PC必然涉及多个DN操作。
阶段1(PREPARE)中,CN先把事务信息记录在SYS_PENDING_DIST_TRANS中,标识事务状态为PREPARE,下发PREPARE给所有事务关联主DN。
阶段2(COMMIT)中,CN审查所有DN返回的预提交结果,如果所有主DN都可以提交,CN标识事务状态为COMMIT,并下发所有主DN做正式提交,这样该全局事务被提交。如果有任一主DN的PREPARE、COMMIT返回失败,CN将要求所有其它主DN回滚该事务操作,这样该全局事务被回滚。
注意:zengine.ini中CN配置参数tc_level配置为0时,CN不再把事务信息记录在SYS_PENDING_DIST_TRANS表中,需要参考情形2处理。
约束:提交或者回滚事务分支时,操作用户为事务的创建用户。
情形1:故障CN可访问
- 查看CN上事务状态。
- 以omm身份登录故障CN所在服务器。
- 在故障CN上以本地登录方式使用zsql连接数据库。
zsql / as clsmgr
- (可选)如果使用zsql连接失败,需要使用如下命令手工启动CN进程后再使用命令“zsql / as clsmgr”本地登录故障CN。
zengine open --coordinator -D cn_data_dir
查看CN上的2PC状态。
SELECT * FROM SYS.SYS_PENDING_DIST_TRANS;
GLOBAL_TRAN_ID TRAN_COMMIT_TIME TRX_STATUS NEED_CLEAN
-------------- -------------------------------- ------------ ------------
4B010900843D310101000000 0 1
DE6F0500F811310101000000 1 1
F2700500FB11310101000000 0 1TRX_STATUS值为0时,表示该事务状态为PREPARE;TRX_STATUS值为1时,表示该事务状态为COMMIT。
- 查询DN上状态为PREPARED和COMMITTED的事务。
对于CN上ID为GLOBAL_TRAN_ID的事务,DBA用户需要在所有DN上根据GLOBAL_TRAN_ID+format_id来查询对应的事务,之后根据CN和DN上查询出来的事务状态进行提交或回滚两阶段事务操作。
- 使用DBA用户登录DN。
zsql omm@192.168.0.1:40000
Please enter password:
***********omm为安装后创建的系统管理员,其默认密码是gaussdb_123。192.168.0.1为DN所在的服务器IP地址,40000为连接的端口号。
- 查询DN上状态为PREPARED的记录。
DN上状态为PREPARED的事务可通过查询表SYS.DV_GLOBAL_TRANSACTIONS获取。
SELECT * FROM SYS.DV_GLOBAL_TRANSACTIONS;
GLOBAL_TRAN_ID FORMAT_ID BRANCH_ID
LOCAL_TRAN_ID STATUS
RMID SID
---------------------------------------------------------------- -------------------- ---------------------------------------------------------------- ---------------------------------------------------------------- ---------------------------------------------------------------- ------------ ------------
3F030C0028DF310101000000 247 0000
1.10185.5 PREPARED
65535 54 - 查询DN上状态为COMMITTED的记录。
DN上状态为COMMITTED的事务可通过查询表SYS.SYS_PENDING_TRANS获取。
SELECT * FROM SYS.SYS_PENDING_TRANS;
GLOBAL_TRAN_ID LOCAL_TRAN_ID TLOCK_LOBS
TLOCK_LOBS_EXT FORMAT_ID BRANCH_ID
OWNER
---------------------------------------------------------------- -------------------- ---------------------------------------------------------------- ---------------------------------------------------------------- -------------------- ---------------------------------------------------------------- ------------
41030C0028DF310101000000 22161391640
0100000000000000000000002100000008000000 247 0000
2
- 使用DBA用户登录DN。
- 根据CN和DN上查询到的2PC状态确定事务操作。
对于CN上ID为GLOBAL_TRAN_ID的事务,DBA用户在所有DN上根据GLOBAL_TRAN_ID+format_id来查询对应的事务之后,可根据CN和DN上查询出来的事务状态进行提交或回滚两阶段事务操作,具体规则请参见表2。
DN上通过查询表SYS.DV_GLOBAL_TRANSACTIONS获取的事务的状态均为PREPARED。
DN上通过查询表SYS.SYS_PENDING_TRANS获取的事务的状态均为COMMITTED。
表2 CN-DN 2PC状态操作对照表 CN上2PC状态(SYS_PENDING_DIST_TRANS中TRX_STATUS的值)
DN上2PC状态
CN和DN上需进行的事务操作
PREPARE(0)
PREPARED
强制ROLLBACK。
PREPARE(0)
COMMITTED
无此情形。
PREPARE(0)
COMMITTED,且事务记录已在SYS_PENDING_TRANS表中删除
无此情形。
COMMIT(1)
PREPARED
强制COMMIT。
COMMIT(1)
COMMITTED
强制COMMIT。
COMMIT(1)
COMMITTED,且事务记录已在SYS_PENDING_TRANS表中删除
正常数据,无需处理。
- 根据步骤3中确定的事务操作在CN和DN上处理事务。
- 定义XID为查询表SYS.DV_GLOBAL_TRANSACTIONS的返回参数按照操作命令拼接而成的字符串,格式为FORMAT_ID.GLOBAL_TRAN_ID.BRANCH_ID。其中,FORMAT_ID默认247,可以在cfg/zengine.ini中指定XA_FORMAT_ID = XXX调整默认值。
- 连接数据库。
- 在CN上回滚事务时,通过CN端口以clsmgr身份连接数据库。
zsql / as clsmgr
如果使用zsql连接失败,需要使用如下命令手工启动CN进程后再使用命令“zsql / as clsmgr”本地登录故障CN。
zengine open --coordinator -D cn_data_dir
- 在DN上回滚事务时,通过DN端口以DBA用户身份连接数据库。
zsql omm@127.0.0.1:40000
Please enter password:
***********omm为安装后创建的系统管理员,其默认密码是gaussdb_123。
40000为DN的端口号,可以通过查看安装配置文件clusterconfig.xml中dataPortBase对应的值确认自定义的DN端口号。
127.0.0.1为本节点IP,如果要连接其他节点上的DN,此处应为其他节点的IP。
- 在CN上回滚事务时,通过CN端口以clsmgr身份连接数据库。
- 处理事务。
在CN上进行的操作为强制删除事务信息,注意删除事务信息需要确保DN已操作完成,CN上的数据为残留数据。
select DBMS_UTILITY.clean_xa_dist_trans('GLOBAL_TRAN_ID') from dual;
其中GLOBAL_TRAN_ID即为CN上表SYS.SYS_PENDING_TRANSPENDING_TRANS$字段GLOBAL_TRAN_ID串值。
在DN上需要进行的事务操作分为强制ROLLBACK和强制COMMIT两种,具体操作步骤分别介绍如下。
- 强制回退两阶段事务。
ROLLBACK PREPARED 'XID';
强制回滚事务示例:
ROLLBACK PREPARED '247.4B010900843D310101000000.0000';
Succeed.
- 强制提交两阶段事务。
COMMIT PREPARED 'XID';
情形2:故障CN无法访问
- 强制回退两阶段事务。
当故障CN无法访问时,可查询所有DN的SYS.PENDING_TRANS表,通过数据分析是否有残留2PC记录,判断是否需要强制回滚或强制提交。该情形下需要DBA结合业务分析。
- 确定故障CN的NODE ID。
- 查询DN上状态为PREPARED和COMMITTED的事务。
对于CN上ID为GLOBAL_TRAN_ID的事务,DBA用户需要在所有DN上根据GLOBAL_TRAN_ID+format_id来查询对应的事务,之后根据DN上查询出来的事务状态进行提交或回滚两阶段事务操作。
- 使用DBA用户登录DN。
zsql omm@192.168.0.1:8000
Please enter password:
***********omm为安装后创建的系统管理员,其默认密码是gaussdb_123。192.168.0.1为DN所在的服务器IP地址,40000为连接的端口号。
- 查询DN上状态为PREPARED的记录。
DN上状态为PREPARED的事务可通过查询表SYS.DV_GLOBAL_TRANSACTIONS获取。
SELECT * FROM SYS.DV_GLOBAL_TRANSACTIONS;
GLOBAL_TRAN_ID FORMAT_ID BRANCH_ID
LOCAL_TRAN_ID STATUS
RMID SID
---------------------------------------------------------------- -------------------- ---------------------------------------------------------------- ---------------------------------------------------------------- ---------------------------------------------------------------- ------------ ------------
3F030C0028DF310101000000 247 0000
1.10185.5 PREPARED
65535 54 - 查询DN上状态为COMMITTED的记录。
DN上状态为COMMITTED的事务可通过查询表SYS.SYS_PENDING_TRANS获取。
SELECT * FROM SYS.SYS_PENDING_TRANS;
GLOBAL_TRAN_ID LOCAL_TRAN_ID TLOCK_LOBS
TLOCK_LOBS_EXT FORMAT_ID BRANCH_ID
OWNER
---------------------------------------------------------------- -------------------- ---------------------------------------------------------------- ---------------------------------------------------------------- -------------------- ---------------------------------------------------------------- ------------
41030C0028DF310101000000 22161391640
0100000000000000000000002100000008000000 247 0000
2
- 使用DBA用户登录DN。
- 在DN上需要进行的事务操作分为强制ROLLBACK和强制COMMIT两种,具体操作步骤分别介绍如下。
- 定义XID为查询表SYS.DV_GLOBAL_TRANSACTIONS的返回参数按照操作命令拼接而成的字符串,格式为FORMAT_ID.GLOBAL_TRAN_ID.BRANCH_ID。其中,FORMAT_ID默认247,可以在cfg/zengine.ini中指定XA_FORMAT_ID = XXX调整默认值。
- 强制回退两阶段事务。
对于DN上状态为PREPARED的事务,即查询表SYS.DV_GLOBAL_TRANSACTIONS获取的事务记录,需要强制回退两阶段事务。需要注意的是,该操作可能导致数据不一致。
ROLLBACK PREPARED 'XID';
强制回滚事务示例:ROLLBACK PREPARED '247.4B010900843D310101000000.0000';
Succeed.
- 强制提交两阶段事务。
对于DN上状态为COMMITTED的事务,即查询表SYS.SYS_PENDING_TRANS获取的事务记录,需要强制提交两阶段事务。
COMMIT PREPARED 'XID';