共计 15106 个字符,预计需要花费 38 分钟才能阅读完成。
- GreatSQL 社区原创内容未经受权不得随便应用,转载请分割小编并注明起源。
[toc]
本文介绍 MGR 的选主算法,以及当 MGR 集群中有多个不同版本混搭时,如何能力失常运行,有什么注意事项。
1. 选主算法
MGR 运行在单主模式时,当产生主节点切换,就须要进行选主工作。多主模式下,所有节点都是主节点,就不须要选主了。
MGR 的选主工作是主动的,每个节点都会参加。选主时会查看以后最新的组视图,对潜在的新主节点(各个备选节点)进行排序,最初选出最合适的那个作为新的主节点。
不同的 MySQL 版本选主算法略有不同,各节点选主时会依据以后的 MySQL 版本选主算法而决定,因而当 MGR 集群中有多个版本并存时,则此时 MGR 会做出调整,以便各个不同版本的节点都能就选主达成算法统一。
通常而言,选主算法的各个因素优先级程序如下:
- 依据 MySQL 版本号排序,低版本的优先级更高(因为要向下兼容)。如果是 MySQL 8.0.17 及以上版本,则优先依据补丁版本号排序(例如 17、18、20)。如果是 8.0.16 及以下版本,则优先依据主版本号排序(例如 5.7、8.0)。
- 版本号雷同的各节点则依据各节点的权重值排序,权重越高优先级也越高。节点的权重值可通过设置
group_replication_member_weight
选项来调整。这个选项是 MySQL 8.0 版本引入的,如果是 5.7 版本则不反对。 - 当版本号和节点权重值都一样时,再依据
server_uuid
(或者说是MEMBER_ID
)排序(留神,不是server_id
),排在后面的优先级越高。MySQL Server 在启动时,会生成一个随机的 UUID 值,其值记录在文件 datadir/auto.cnf 文件中,实际上能够在实例启动前,通过批改这个 UUID 值来扭转server_uuid
的值,只有合乎 UUID 数据格式即可。因而,相当于是能够认为调整server_uuid
以调整选主时节点的排序优先级。
从下面可知,当有 MySQL 8.0 和 5.7 的节点混搭运行 MGR 集群时,运行 5.7 版本的节点会优先被选中,其次再依据 group_replication_member_weight
抉择权重搞的节点,最初再依据 server_uuid
排序。
因而,运行 MGR 集群时最好各节点版本号雷同,选主规定就简略多了。
在 MySQL 8.0 中,通过查问 performance_schema.replication_group_members
表的 MEMBER_ROLE
即可晓得哪个是主节点:
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 4ebd3504-11d9-11ec-8f92-70b5e873a570 | 172.16.16.10 | 3306 | ONLINE | PRIMARY | 8.0.25 | <--- 主节点
| group_replication_applier | 549b92bf-11d9-11ec-88e1-70b5e873a570 | 172.16.16.11 | 3307 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | 5596116c-11d9-11ec-8624-70b5e873a570 | 172.16.16.12 | 3308 | ONLINE | SECONDARY | 8.0.25 |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+
如果是在 MySQL 5.7 中,则须要通过查问 group_replication_primary_member
这个 status 能力晓得,比 8.0 麻烦。所以说,还是尽量应用 MySQL 8.0 来构建 MGR 集群。
在一个 MySQL 5.7 和 8.0 混搭的 MGR 集群中,从运行 MySQL 8.0 版本的节点上看到的状态是这样的:
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+
| group_replication_applier | af39db70-6850-11ec-94c9-00155d064000 | 172.16.16.13 | 3306 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | d9833e7e-6ecc-11ec-a3f6-d08e7908bcb1 | 172.16.16.10 | 3306 | ONLINE | PRIMARY | 5.7.36 |
| group_replication_applier | fe55e195-6ecc-11ec-a2e9-d08e7908bcb1 | 172.16.16.11 | 3306 | ONLINE | SECONDARY | 5.7.36 |
| group_replication_applier | ff19317f-6ecc-11ec-b17d-d08e7908bcb1 | 172.16.16.12 | 3306 | ONLINE | SECONDARY | 5.7.36 |
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+
能够看到,即使是运行 MySQL 8.0 版本的节点的 server_uuid
排序在后面,但在主动选主时,也不会被选中作为主节点。此外,运行 MySQL 5.7 版本的节点是无奈退出主节点运行 MySQL 8.0 的 MGR 集群的,会报告相似上面的谬误:
[ERROR] Plugin group_replication reported: 'Member version is incompatible with the group'
提醒版本不兼容。
2. 多版本兼容性
失常地,为了 MGR 的兼容性及性能,所有节点的 MySQL 版本最好保持一致。尤其是在多主模式下,各节点都提供写入服务,如果兼容性方面存在问题,则可能会导致 MGR 集群异样或写入异样。为了防止这种状况产生,新退出节点时,会和其余节点进行版本兼容性查看。
目前 MGR 反对 3 个通信协议版本号:5.7.14、8.0.16、8.0.27,这几个版本的次要变动有:
- 从 5.7.14 开始,反对消息压缩。
- 从 8.0.16 开始,反对音讯分片。
- 从 8.0.27 开始,反对在单主模式下,设置惟一的 leader 节点。
MGR 集群中,各节点间的通信协议版本号必须统一,这样能力保障即便是 MySQL 版本号不统一,但 MGR 通信仍然不受影响。新退出节点的通信协议版本号必须高于以后集群中应用的通信协议版本。节点退出时会查看协定版本,并向其播送以后集群中应用的协定版本,如果能够兼容,则容许退出,否则会将其踢出。
当两个节点同时退出时,只有当两个节点的通信协议版本和集群兼容时,能力同时退出胜利。和以后集群不同协定版本的节点须要独自退出才行,例如:
- 一个应用 8.0.16 版本的实例能够胜利退出应用通信协议版本 5.7.24 的集群。
- 一个 5.7.24 实例无奈退出应用 8.0.16 的集群。
- 两个 8.0.16 实例无奈同时退出应用 5.7.24 的集群。
- 两个 8.0.16 实例能够同时退出应用 8.0.16 的集群。
如果有须要,还能够在线批改通信协议版本号,应用 group_replication_set_communication_protocol()
这个 UDF 即可(MySQL 8.0 以上反对),例如:
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.25-15 | <-- 以后 MySQL 版本是 8.0.25
+-----------+
1 row in set (0.00 sec)
mysql> select group_replication_get_communication_protocol();
+------------------------------------------------+
| group_replication_get_communication_protocol() |
+------------------------------------------------+
| 8.0.16 | <-- 以后 MGR 通信协议版本是 8.0.16
+------------------------------------------------+
1 row in set (0.00 sec)
mysql> select group_replication_set_communication_protocol('5.7.14');
+-----------------------------------------------------------------------------------+
| group_replication_set_communication_protocol('5.7.14') | <-- 手动批改通信协议版本为 5.7.14,能够胜利
+-----------------------------------------------------------------------------------+
| The operation group_replication_set_communication_protocol completed successfully |
+-----------------------------------------------------------------------------------+
mysql> select group_replication_set_communication_protocol('8.0.25');
+-----------------------------------------------------------------------------------+
| group_replication_set_communication_protocol('8.0.25') |
+-----------------------------------------------------------------------------------+
| The operation group_replication_set_communication_protocol completed successfully | <-- 批改协定版本为 8.0.25,接下来看看会产生什么
+-----------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select group_replication_get_communication_protocol();
+------------------------------------------------+
| group_replication_get_communication_protocol() |
+------------------------------------------------+
| 8.0.16 | <-- 重置为 8.0.16
+------------------------------------------------+
# 尝试批改为 8.0.27,会报错
mysql> select group_replication_set_communication_protocol('8.0.27');
ERROR 1123 (HY000): Can't initialize function'group_replication_set_communication_protocol'; 8.0.27 is not between 5.7.14 and 8.0.25
其实说这么多版本兼容性的话题,还不如一个简略的准则: 让所有节点的版本号都统一 。这样构建 MGR 集群更简略,节点间通信也不会被复杂化。
3. MGR 5.7 滚动降级至 8.0
MGR 5.7 集群滚动降级至 8.0 能够参考这篇文章:MySQL MGR 从 5.7 滚动降级至 8.0,简言之,能够分为以下几步:
- 在现有 MGR 5.7 集群中,新增 MySQL 8.0 的 Secondary 节点。
- 一比一下线一个 MySQL 5.7 的 Secondary 节点。
- 如此往返,直到剩下最初一个 MySQL 5.7 的 Primary 节点。
- 再次上线一个 MySQL 8.0 的 Secondary 节点。
- 进行最初一个 MySQL 5.7 的 Primary 节点,这是会切换主节点,并且抉择其中一个 MySQL 8.0 节点作为新的 Primary 节点,这就实现降级了。
在这里实操演示大略的过程。
在 MGR 5.7 的集群中,减少一个 MySQL 8.0 的 Secondary 节点:
# 在 5.7 节点上看节点状态
#原生的 MySQL 5.7 MGR 看不到 MEMBER_ROLE 这列
#这是 GreatSQL 5.7 新增的个性
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+
| group_replication_applier | c8ec34c4-78fc-11ec-864a-111111111111 | 127.0.0.1 | 4306 | ONLINE | PRIMARY |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-222222222222 | 127.0.0.1 | 4307 | ONLINE | SECONDARY |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-333333333333 | 127.0.0.1 | 4308 | ONLINE | SECONDARY |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888333 | 127.0.0.1 | 3309 | ONLINE | SECONDARY |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+
#在 8.0 节点上看
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | c8ec34c4-78fc-11ec-864a-111111111111 | 127.0.0.1 | 4306 | ONLINE | PRIMARY | 5.7.36 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-222222222222 | 127.0.0.1 | 4307 | ONLINE | SECONDARY | 5.7.36 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-333333333333 | 127.0.0.1 | 4308 | ONLINE | SECONDARY | 5.7.36 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888333 | 127.0.0.1 | 3309 | ONLINE | SECONDARY | 8.0.25 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
当初,利用 MySQL Shell 删除一个旧节点:
c.removeInstance('127.0.0.1:4308');
The instance will be removed from the InnoDB cluster. Depending on the instance
being the Seed or not, the Metadata session might become invalid. If so, please
start a new session to the Metadata Storage R/W instance.
Instance '127.0.0.1:4308' is attempting to leave the cluster...
WARNING: On instance '127.0.0.1:4308' configuration cannot be persisted since MySQL version 5.7.36 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please set the 'group_replication_start_on_boot' variable to 'OFF' in the server configuration file, otherwise it might rejoin the cluster upon restart.
WARNING: Instance '127.0.0.1:4306' cannot persist configuration since MySQL version 5.7.36 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please use the dba.configureLocalInstance() command locally to persist the changes.
The instance '127.0.0.1:4308' was successfully removed from the cluster.
之后再查看节点状态:
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | c8ec34c4-78fc-11ec-864a-111111111111 | 127.0.0.1 | 4306 | ONLINE | PRIMARY | 5.7.36 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-222222222222 | 127.0.0.1 | 4307 | ONLINE | SECONDARY | 5.7.36 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888333 | 127.0.0.1 | 3309 | ONLINE | SECONDARY | 8.0.25 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
如此往返,直到只剩最初一个 5.7 节点:
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | c8ec34c4-78fc-11ec-864a-111111111111 | 127.0.0.1 | 4306 | ONLINE | PRIMARY | 5.7.36 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888333 | 127.0.0.1 | 3309 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888444 | 127.0.0.1 | 3310 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888555 | 127.0.0.1 | 3311 | ONLINE | SECONDARY | 8.0.25 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
敞开最初一个 5.7 节点,会主动切换主节点:
MySQL 127.0.0.1:4306 ssl JS > c.removeInstance('127.0.0.1:4306');
The instance will be removed from the InnoDB cluster. Depending on the instance
being the Seed or not, the Metadata session might become invalid. If so, please
start a new session to the Metadata Storage R/W instance.
Instance '127.0.0.1:4306' is attempting to leave the cluster...
WARNING: On instance '127.0.0.1:4306' configuration cannot be persisted since MySQL version 5.7.36 does not support the SET PERSIST command (MySQL version >= 8.0.11 required). Please set the 'group_replication_start_on_boot' variable to 'OFF' in the server configuration file, otherwise it might rejoin the cluster upon restart.
The instance '127.0.0.1:4306' was successfully removed from the cluster.
之后能够看到 5.7 节点全副下线了,只剩下 8.0 节点:
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888333 | 127.0.0.1 | 3309 | ONLINE | PRIMARY | 8.0.25 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888444 | 127.0.0.1 | 3310 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | c8ec34c4-78fc-11ec-864a-888888888555 | 127.0.0.1 | 3311 | ONLINE | SECONDARY | 8.0.25 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
查看切换过程:
2022-01-20T22:19:10.753644+08:00 0 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: 127.0.0.1:4306'
2022-01-20T22:19:10.753648+08:00 0 [System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address 127.0.0.1:4306 left the group. Electing new Primary.'
2022-01-20T22:19:10.753705+08:00 0 [Note] [MY-011071] [Repl] Plugin group_replication reported: 'handle_leader_election_if_neede
d is activated,suggested_primary:'2022-01-20T22:19:10.754747+08:00 0 [Note] [MY-013519] [Repl] Plugin group_replication reported:'Elected primary member gtid_exe
cuted: 082b900b-79d5-11ec-8fe2-00155d064000:1-32, 36ab409a-79d6-11ec-9cd5-00155d064000:1-37'2022-01-20T22:19:10.754790+08:00 0 [Note] [MY-013519] [Repl] Plugin group_replication reported:'Elected primary member applier
channel received_transaction_set: 082b900b-79d5-11ec-8fe2-00155d064000:1-32, 36ab409a-79d6-11ec-9cd5-00155d064000:1-37'2022-01-20T22:19:11.754969+08:00 0 [System] [MY-011507] [Repl] Plugin group_replication reported:'A new primary with address ye
jr.run:3309 was elected. The new primary will execute all previous group transactions before allowing writes.'2022-01-20T22:19:11.755803+08:00 92 [System] [MY-011566] [Repl] Plugin group_replication reported:'Setting super_read_only=OFF.
'2022-01-20T22:19:12.752517+08:00 0 [Note] [MY-011735] [Repl] Plugin group_replication reported:'[GCS] Failure reading from fd=5
3 n=0'2022-01-20T22:19:12.755961+08:00 0 [System] [MY-011503] [Repl] Plugin group_replication reported:'Group membership changed to y
ejr.run:3309, 127.0.0.1:3310, 127.0.0.1:3311 on view 16426721489193731:9.'2022-01-20T22:19:12.756296+08:00 91 [System] [MY-011566] [Repl] Plugin group_replication reported:'Setting super_read_only=OFF.
'2022-01-20T22:19:12.756744+08:00 91 [System] [MY-011510] [Repl] Plugin group_replication reported:'This server is working as pr
imary member.'2022-01-20T22:19:12.756787+08:00 30 [Note] [MY-011485] [Repl] Plugin group_replication reported:'Primary had applied all relay
logs, disabled conflict detection.'
这就实现滚动降级了。
4. 小结
本文介绍了 MGR 集群中是如何进行选主的,当有 5.7、8.0 版本混合时的兼容性,以及如何把 MGR 5.7 滚动降级到 8.0。最初多说一句,哪怕是不必 MGR,8.0 绝对 5.7 还是有很多企业级个性,5.6、5.7 也只能是过渡版本,最终还是强烈建议降级到 8.0 版本。
参考资料、文档
- MySQL 8.0 Reference Manual
- 数据库内核开发 – 温正湖
- Group Replication 原理 – 宋利兵
免责申明
因集体程度无限,专栏中不免存在错漏之处,请勿间接复制文档中的命令、办法间接利用于线上生产环境。请读者们务必先充沛了解并在测试环境验证通过前方可正式施行,防止造成生产环境的毁坏或侵害。
Enjoy GreatSQL :)
文章举荐:
GreatSQL 季报(2021.12.26)
https://mp.weixin.qq.com/s/FZ…
技术分享 |sysbench 压测工具用法浅析
https://mp.weixin.qq.com/s/m1…
故障剖析 | linux 磁盘 io 利用率高,剖析的正确姿态
https://mp.weixin.qq.com/s/7c…
技术分享 | 闪回在 MySQL 中的实现和改良
https://mp.weixin.qq.com/s/6j…
万答 #20,索引下推如何进行数据过滤
https://mp.weixin.qq.com/s/pt…
对于 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 公布!