MySQL MGR集群搭建

本文来自网易云社区,转载务必请注明出处。


本文将从零开始搭建一个MySQL Group Replication集群,包含3个节点。简单介绍如何查询MGR集群状态信息。并介绍如何进行MGR节点上下线操作。先贴一份MySQL配置文件,如下:


explicit_defaults_for_timestamp=ON

# server configuration

datadir=/home/innosql/innosql/data/

basedir=/home/innosql/mysql/

port=3306

socket=/home/innosql/innosql/mysql.sock

#如果节点得hostname无法通过DNS正常解析,需要配置report_host

#report_host=10.200.128.67

max_allowed_packet=16M

max_connections=65536

log_error

#MGR要求和约束 详见https://dev.mysql.com/doc/refman/5.7/en/group-replication-requirements-and-limitations.html

server_id=1

gtid_mode=ON

enforce_gtid_consistency=ON

master_info_repository=TABLE

relay_log_info_repository=TABLE

binlog_checksum=NONE

log_slave_updates=ON

log_bin=binlog

binlog_format=ROW

#super_read_only=ON

slave_parallel_type=logical_clock

slave_parallel_workers=16

slave_preserve_commit_order=ON

transaction_write_set_extraction=XXHASH64

#MGR参数配置 详见 https://dev.mysql.com/doc/refman/5.7/en/group-replication-options.html

loose-group_replication_enforce_update_everywhere_checks = ON

loose-group_replication_single_primary_mode = OFF

loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"

loose-group_replication_start_on_boot=off

loose-group_replication_local_address= "mgr-node1.163.org:10086"

loose-group_replication_group_seeds= "mgr-node1.163.org:10086,mgr-node2.163.org:10086,mgr-node3.163.org:10086"

loose-group_replication_bootstrap_group= off


为了表示方便,我们将三个节点命名为mgr-node1、mgr-node2和mgr-node3。在mgr-node1上初始化MySQL,并启动MySQL:


./mysql/bin/mysqld --defaults-file=/home/innosql/innosql/my-mgr.cnf --initialize-insecure

./mysql/bin/mysqld --defaults-file=/home/innosql/innosql/my-mgr.cnf &


登陆到mgr-node1客户端,(可用通过mysql的prompt参数来设置客户端显示的提示信息),安装group_replication插件:


mgr-node1>INSTALL PLUGIN group_replication SONAME 'group_replication.so';

Query OK, 0 rows affected (0.01 sec)


我们已经在配置文件中包含了所有MGR所需的命令参数。比如组名称group_replication_group_name,该参数必须为一个合法的UUID字符串。设置了本节点的MGR模块通信地址group_replication_local_address,MGR集群的成员种子group_replication_group_seeds,该参数用于在异步故障恢复时选择合适的数据贡献者(donor)。在配置文件中,我们启用了多主模式,即设置group_replication_single_primary_mode为off。对于同一个复制组的成员,必须确保他们各自的MGR相关配置不冲突,如group_replication_single_primary_mode、group_replication_enforce_update_everywhere_checks等。需要注意的是请在配置文件中将group_replication_bootstrap_group设置为off,该参数表示是否执行MGR复制组的初始化操作,通俗得说,如果该参数为on,那么会新建一个MGR复制组。由于在我们的例子中,server1是第一个初始化节点,所以,我们动态开启该参数,然后再启动MGR:


mgr-node1>set global group_replication_bootstrap_group=on;

Query OK, 0 rows affected (0.00 sec)

mgr-node1>start group_replication;

Query OK, 0 rows affected (2.05 sec)

mgr-node1>set global group_replication_bootstrap_group=off;

Query OK, 0 rows affected (0.00 sec)


如上图所示,在启动MGR后,我们关闭了group_replication_bootstrap_group,确保下一次该节点启动的时候不会再次进行初始化。导致复制组出现分裂。我们可以查询当前MGR成员状态:


mgr-node1>select * from replication_group_members;

+---------------------------+--------------------------------------+---------------------+-------------+--------------+

| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+---------------------+-------------+--------------+

| group_replication_applier | 2c4518a5-d4b4-11e7-a736-246e964083f0 | mgr-node1.163.org | 3306 | ONLINE |

+---------------------------+--------------------------------------+---------------------+-------------+--------------+


1 row in set (0.00 sec)

由于mgr-node1是第一个成员,所以members列表中仅有一个成员,可以看到起状态是ONLINE,说明正常运行中。接下来创建一个账号,权限为REPLICATION SLAVE ,该账号为用于故障恢复的异步复制通道group_replication_recovery所用。MGR组复制所需的group_replication_applier通道不需要我们设置账号和密码。依次在server1客户端执行如下SQL:


CREATE USER rpl_user@'%';

GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'rpl_pass';

FLUSH PRIVILEGES;


基于该账号设置group_replication_recovery复制通道,如下:


mgr-node1>CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery';

Query OK, 0 rows affected, 2 warnings (0.01 sec)


上述就完成了第一个MGR节点初始化,接下来2个节点加入MGR执行的操作类似。但有个点需要指出:将第二个节点mgr-node2加入复制组前,除了确保group_replication_bootstrap_group处于关闭状态之外,还需先执行CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery'再执行start group_replication。在mgr-node1加入组后,我们创建了复制用户rpl_user,并执行了CHANGE MASTER TO,但其实并没有发挥作用。而在mgr-node2,CHANGE MASTER TO才真正发挥作用,在start group_replication中,mgr-node2会根据配置文件中指定seeds参数找到mgr-node1,并使用rpl_user这个账号连接到mgr-node1,拉取该节点的Binlog信息。所以mgr-node1上创建的用户,是给其他节点加组或故障恢复用的,并不是给本节点用。


与官方手册或网上的一些MGR搭建步骤不一样,我们的步骤中并没有在mgr-node2和mgr-node3上创建rpl_user用户,因为该用户可以通过Binlog从mgr-node1上复制到这两个节点。这应该是更加简洁的MGR搭建方式,不知为何官方分别在三个节点上创建rpl_user,为了避免复制冲突,又在创建前设置了session的sql_log_bin参数为off。新节点加入复制组的时候,其状态为RECOVERING,如下:


mgr-node1>use performance_schema;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mgr-node1>select * from replication_group_members;

+---------------------------+--------------------------------------+---------------------+-------------+--------------+

| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+---------------------+-------------+--------------+

| group_replication_applier | 2c4518a5-d4b4-11e7-a736-246e964083f0 |mgr-node1.163.org | 3306 | ONLINE |

| group_replication_applier | 567f80c2-d65c-11e7-87a8-246e963b4310 |mgr-node2.163.org | 3306 | RECOVERING |

| group_replication_applier | fb08ecba-d65c-11e7-a74f-246e963b3e60 | mgr-node3.163.org | 3336 | RECOVERING |

+---------------------------+--------------------------------------+---------------------+-------------+--------------+


我们把加入组到状态变为ONLINE分为三个阶段,分别为本地恢复、全局恢复和缓存事务执行。本地恢复阶段会检查节点本地Relay Log中是否有可执行的Event,若有,则先执行完这部分Binlog。接下来进入到拉取本节点加入组之前复制组产生的而本节点没有的Binlog信息并回放。最后是缓存事务执行阶段,会将加入组之后产生的Binlog信息进行回放,这部分信息已事先缓存在本节点上。这三个节点回放Binlog/Relay Log所使用的复制通道分别是group_replication_applier、group_replication_recovery和group_replication_applier。


上面还有个问题,那就是如何区分第二和第三个阶段。这就需要提到View_change_log_event,该类型的Binlog Event为MGR所用,用于记录复制组中成员变化情况,每次成员加入或退出均会被记录为一个新的Binlog Event,也就在Binlog中表达了一个组视图(Group View)。回到本例,mgr-node2和mgr-node3加入组时,都会产生一个View_change_log_event,只需要在第二阶段获取Binlog时判断是否读到了当前视图的View_change_log_event即可。


在复制组生命周期内,成员的加入或删除都可以参考上述流程顺利完成。但有一种特殊情况需要考虑。那就是如果万一组中所有成员都下线了,第一个上线的节点就无法按照上述的恢复流程顺利上线,因为第二阶段不能顺利完成,无法找到合适的种子拉取以前的Binlog信息。所以,此时需要特殊处理,即第一个节点起来执行start group_replication前需要设置group_replication_bootstrap_group为on。

MySQL为MGR提供了丰富的监控信息,基本上在performance_schema系统库中,除了上述的replication_group_members外,还有replication_group_member_stats、replication_connection_status和replication_applier_status等。


本文主要介绍了如何搭建一个MGR集群,并未展开描述MGR的相关特性。感兴趣的同学可以查阅MGR官方手册,其中对MGR做了较为全面的介绍,是MGR入门的好帮手。



本文来自网易云社区 ,经作者温正湖授权发布。

网易云免费体验馆,0成本体验20+款云产品!

更多网易研发、产品、运营经验分享请访问网易云社区



相关文章:
【推荐】 IT和非IT人士:2分钟了解什么是区块链
【推荐】 【工具使用】Android调试利器之LLDB
【推荐】 30分钟,让你彻底明白Promise原理

推荐阅读更多精彩内容