乐趣区

关于mysql:有事务冲突时节点怎么加入MGR集群

  • GreatSQL 社区原创内容未经受权不得随便应用,转载请分割小编并注明起源。

[toc]

个别节点可能存在事务抵触,导致无奈退出 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,尽管遇到数据抵触、数据不存在等报错时能主动疏忽跳过,但长此以往,可能数据不统一的状况越来越重大,等到某天无可奈何要切换主节点时,就压根不敢切了,那时悔之晚矣。

就这,全文完。

Enjoy GreatSQL :)

文章举荐:

面向金融级利用的 GreatSQL 正式开源
https://mp.weixin.qq.com/s/cI…

Changes in GreatSQL 8.0.25 (2021-8-18)
https://mp.weixin.qq.com/s/qc…

MGR 及 GreatSQL 资源汇总
https://mp.weixin.qq.com/s/qX…

GreatSQL MGR FAQ
https://mp.weixin.qq.com/s/J6…

在 Linux 下源码编译装置 GreatSQL/MySQL
https://mp.weixin.qq.com/s/WZ…

# 对于 GreatSQL

GreatSQL 是由万里数据库保护的 MySQL 分支,专一于晋升 MGR 可靠性及性能,反对 InnoDB 并行查问个性,是实用于金融级利用的 MySQL 分支版本。

Gitee:

https://gitee.com/GreatSQL/Gr…

GitHub:

https://github.com/GreatSQL/G…

Bilibili:

https://space.bilibili.com/13…

微信 &QQ 群:

可搜寻增加 GreatSQL 社区助手微信好友,发送验证信息“加群”退出 GreatSQL/MGR 交换微信群

QQ 群:533341697

微信小助手:wanlidbc

本文由博客一文多发平台 OpenWrite 公布!

退出移动版