DWS CN事务号回卷故障构造及恢复
涉及版本:C80及以下版本
相关原理:http://mysql.taobao.org/monthly/2018/03/08/
从6.5.1版本开始,DWS采用64位事务号,不再存在此问题。此帖只用于技术交流。
此方案属于高危操作,严禁用户与一线、二线在生产集群操作!操作不慎会导致集群无法修复的严重后果!
场景一:CN回卷,且正常cn的nextxid未超过21亿
1. 确认集群状态:3c18d
确认gtm主备
2. 在三个cn分别执行
select txid_current();
select * from pg_get_xidlimit();
确定事务号当前处于正常状态
3. 将主gtm的gtm.control中,xid的值改为19亿,然后kill -9 主gtm
4. 查询事务号情况
5. 在所有cn都执行vacuum freeze,推进oldestXid至18亿
6. 将gtm.control中xid的值改为39亿,kill -9 主gtm,并且只在cn5001和cn5002执行vacuum freeze
cn5001和cn5002的事务号变成下图的情况(nextXid39亿,oldestXid推进到38亿)
cn5003的事务号变成下图的情况(nextXid39亿,oldestXid仍为18亿)
7. 将gtm.comtrol中xid的值改为49亿,kill -9 主gtm
在cn5001和cn5002执行select txid_current()可以正常执行。查看事务号情况,nextXid回卷至6亿,oldestXid为38亿,还可以正常运行
在cn5003执行select txid_current()会报错,因为此时cn5003的nextXid为6亿,oldestXid为18亿,无法再执行写事务。场景已复现。
恢复方案:
gs_replace即可
场景二:CN回卷,且正常cn的nextXid已超过21亿
1. 确认集群状态:3c18d
确认gtm主备
2. 在三个cn分别执行
select txid_current();
select * from pg_get_xidlimit();
确定事务号当前处于正常状态
3. 将主gtm.control中xid改为16亿,kill -9 主gtm,并在cn5001和cn5002执行vacuum freeze
此时cn5001和cn5002的nextXid为16亿,oldestXid为15亿
cn5003的nextXid为16亿,oldestXid为5亿
4. 将主gtm.control中xid改为30亿,kill -9 主gtm
此时cn5001和cn5002的nextXid为30亿,oldestXid为15亿,仍可正常使用;cn5003的nextXid为30亿,oldestXid为5亿,问题复现
恢复方案:
1. 停掉集群cm_ctl stop
2. 将cn_5003数据目录进行备份
3. 对cn5003所有绝对表空间的真实目录进行备份(使用mv命令备份)。表空间真实路径可以在pg_tblspc查看,相对表空间因为路径在pg_location下,不用重复备份。(测试环境上只有一个相对表空间,没有绝对表空间,不重复备份)
4. 将cn5001的目录拷贝至cn5003
5. 在cn5001所在节点将所有绝对表空间下的cn5001目录拷贝至cn5003所在节点的对应位置,并重命名为cn5003。相对表空间直接去对应位置重命名即可。重命名之后重建软连接
mv PG_9.2_201611171_cn_5001/ PG_9.2_201611171_cn_5003/
在pg_tblspc重建软连接
6. 从之前备份的cn5003目录中,将pg_hba.conf,pg_ident.conf,postgresql.conf三个文件拷贝回去
7. 启动集群cm_ctl start
8. 连接cn5003,更新pgxc_node
由于cn5003是从cn5001拷贝过来的,pgxc_node中localhost还是cn5001,需要修改
查看当前视图
进行修改
update pgxc_node set (node_host,node_host1)=('localhost','localhost') where node_name = 'cn_5003';
update pgxc_node set (node_host,node_host1)=('100.185.183.29,'100.185.183.29') where node_name = 'cn_5001';
再次查看视图
9. 重启集群
10. 在cn5003创建一张表进行验证
11. 业务验证
- 点赞
- 收藏
- 关注作者
评论(0)