有事务冲突时节点怎么加入MGR集群

  • GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。

个别节点可能存在事务冲突,导致无法加入MGR集群,该怎么处理?

1. 问题场景描述

有些时候,可能因为网络分区等异常情况导致节点意外退出MGR集群,在退出之前可能有些事务还没来得及发送到其他节点。或者可能因为误操作,在这个节点上意外写入数据。那么这个节点重加入MGR集群时,就可能会报告类似下面的错误:

[ERROR] [MY-011526] ... This member has more executed transactions than those present in the group. Local transactions: xx:1-300917674 > Group transactions: xx:1-300917669
[ERROR] [MY-011522] ... The member contains transactions not present in the group. The member will now exit the group.'

这段日志的意思是,本地节点的事务GTID为 1-300917674,而欲加入的MGR集群的事务GTID是 1-300917669,本地节点多了5个事务,因此无法正确加入。

2. 如何修复

遇到这种报错不要慌,我们一起来看下怎么处理。大致可以分为X步走。

2.1 找出事务差异点

首先,根据报错日志,找出本地节点相对于MGR集群多出来的或有差异的事务。在本案中,本地节点多了5个事务,利用mysqlbinlog来看这些事务都涉及到哪些数据对象:

# -vvv,   打印更多冗余信息,方便排查
# --base64-output=decode-rows,进行base64解码
# --include-gtids=,指定要包含的GTID范围
$ mysqlbinlog -vvv --base64-output=decode-rows --include-gtids="0d432272-bddf-11ec-82a9-d08e7908bcb1:300917669-300917674" mgr03.000003 > diff-trxs.sql

接下来就可以对解析出来的SQL文件进行检查,判断影响了哪些数据对象,以及具体哪些数据。

此时,如果MySQL已经设置了 binlog_rows_query_log_events = ON*(这个选项默认值是 OFF,建议改成开启),则binlog里还会记录原始SQL语句,更方便排查了,例如这样:

SET @@SESSION.GTID_NEXT= '0d432272-bddf-11ec-82a9-d08e7908bcb1:300917669'/*!*/;
# at 1412
#220419 16:43:37 server id 3308  end_log_pos 1494 CRC32 0xe0bed25b      Query   thread_id=93    exec_time=0     error_code=0
SET TIMESTAMP=1650357817/*!*/;
BEGIN
/*!*/;
# at 1494
#220419 16:43:37 server id 3308  end_log_pos 1541 CRC32 0xc3635e5d      Rows_query
# insert into t1 select 4   <-- 这里是原始SQL语句
# at 1541
#220419 16:43:37 server id 3308  end_log_pos 1591 CRC32 0x3e190d83      Table_map: `sbtest`.`t1` mapped to number 129
# at 1591
#220419 16:43:37 server id 3308  end_log_pos 1631 CRC32 0x890bd335      Write_rows: table id 129 flags: STMT_END_F
### INSERT INTO `sbtest`.`t1`
### SET
###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
# at 1631
#220419 16:43:37 server id 3308  end_log_pos 1662 CRC32 0x53c6a05a      Xid = 267
COMMIT/*!*/;

2.2 决定如何处理

现在已经知道本地节点和MGR集群相差了哪些数据,就需要进行选择了,看看是要舍弃这些事务数据,还是人工补差。

如果是选择舍弃差异的事务数据,则需要在本地节点对有差异的数据进行回滚,原来是INSERT的数据改成DELETE,原来是DELETE的数据改成INSERT,把新值UPDATE成旧值。也可以利用第三方闪回工具进行恢复。

完成事务回滚后,在MGR集群某个节点执行下面的SQL,查看当前的GTID信息:

mysql> show master status\G
*************************** 1. row ***************************
             File: mgr01.000716
         Position: 6561
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set: 277e7e5e-b711-11ec-9928-d08e7908bcb1:1-46399285:47399284,
277e807f-b711-11ec-9928-d08e7908bcb1:1-31,
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa1:1-26442019,
aaaaaaaa-bbbb-bbbb-aaaa-aaaaaaaaaaa1:1-1853

复制上面的GTID信息,在欲重新加入MGR的节点上执行下面的SQL命令:

# 重置master
mysql> RESET MASTER;

# 重置GTID_PURGED
mysql> SET GLOBAL GTID_PURGED = '277e7e5e-b711-11ec-9928-d08e7908bcb1:1-46399285:47399284,
277e807f-b711-11ec-9928-d08e7908bcb1:1-31,
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa1:1-26442019,
aaaaaaaa-bbbb-bbbb-aaaa-aaaaaaaaaaa1:1-1853';

之后应该就可以直接启动MGR服务,重新加回MGR集群了。

如果是选择手动补足差异的事务数据,首先也是参考上面的方法,解析binlog导出相对应的事务,确认要补差的事务数据。然后执行类似下面的命令,把本地节点多出来的事务应用到MGR集群的Primary节点上,例如下面这样:

# 解析本地binlog,包含有差异的那部分事务数据
# 而后直接利用管道应用到MGR集群的Primary节点上
$ mysqlbinlog -vvv --base64-output=decode-rows --include-gtids="0d432272-bddf-11ec-82a9-d08e7908bcb1:300917669-300917674" mgr03.000003 | mysql -hmgr01 -uGreatSQL -pGreatSQL

补差的事务应用完毕后,再检查两边的GTID差异,然后同样也要执行 RESET MASTER 以及修改 GTID_PURGED 的工作,之后再启动MGR服务即可。

不过,在补完差异数据后,可以直接利用clone重建Secondary实例,再加入MGR集群即可,就不用再手动修改GTID这些麻烦且易错的操作了。在执行clone时,如果数据量较大,也要注意设置选项 clone_max_data_bandwidthclone_max_network_bandwidth 以避免把内网带宽打满。

3. 小结

本文介绍了当某个MGR节点有事务不一致时,如何找到差异的数据,以及如何进行补救。

如果担心数据不一致的话,也可以直接利用clone功能直接重建Secondary节点,也很方便。

另外,线上生产环境中,最好不要设置 slave-skip-erros,虽然遇到数据冲突、数据不存在等报错时能自动忽略跳过,但久而久之,可能数据不一致的情况越来越严重,等到某天迫不得已要切换主节点时,就压根不敢切了,那时悔之晚矣。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MGR(MySQL Group Replication)是MySQL 5.7中新增的高可用性解决方案,它基于Paxos协议实现了多主复制,并且支持自动故障检测和自动故障转移。以下是MGR集群搭建的详细步骤: 1. 确定集群的节点数和角色,至少需要3个节点。其中,至少需要一个节点作为主节点,其他节点作为从节点。 2. 在每个节点上安装MySQL 5.7及以上版本,并且确保每个节点的MySQL配置文件中启用了MGR插件。 3. 在主节点上创建一个新的MGR组,并且将从节点添加到组中。可以使用以下命令: ``` mysql> SET GLOBAL group_replication_bootstrap_group=ON; mysql> CREATE USER 'mgr_user'@'%' IDENTIFIED BY 'password'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'mgr_user'@'%'; mysql> START GROUP_REPLICATION; mysql> SET GLOBAL group_replication_bootstrap_group=OFF; ``` 其中,mgr_user是用于MGR组内节点之间的通信的用户名,password是密码。 4. 在从节点上启动MGR组,并且加入到主节点所在的组中。可以使用以下命令: ``` mysql> SET GLOBAL group_replication_bootstrap_group=OFF; mysql> CHANGE MASTER TO MASTER_USER='mgr_user', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery'; mysql> START GROUP_REPLICATION; ``` 其中,mgr_user和password应该与主节点上设置的相同。 5. 在每个节点上配置MGR的一些参数,比如MGR组的名称、通信端口等等。可以使用以下命令: ``` mysql> SET GLOBAL group_replication_group_name='my_group'; mysql> SET GLOBAL group_replication_local_address='127.0.0.1:33061'; mysql> SET GLOBAL group_replication_group_seeds='127.0.0.1:33061,127.0.0.1:33062,127.0.0.1:33063'; ``` 其中,my_group是MGR组的名称,127.0.0.1:33061是节点的通信地址和端口,group_replication_group_seeds是所有节点的通信地址和端口。 6. 测试MGR集群的可用性。可以通过在主节点上执行一些数据操作,然后在从节点上查看是否同步了这些操作来进行测试。 以上就是MGR集群搭建的详细步骤。需要注意的是,在实际应用中,还需要考虑一些高可用性和安全性方面的问题,比如如何自动故障转移、如何进行备份和恢复、如何保护敏感数据等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值