从MySQL 5.7.17版本开始,MySQL针对异步复制,半同步复制的一些不足,新发布了一种基于Paxos协议的Group_Replicaiton高可用方案,目的是为了数据最终一致性。
HostName |
OS |
MySQL Version |
IP:Port |
CPU |
MEM |
bandwith |
mysql-1 |
CentOS7.3 |
5.7.18 Community |
10.45.81.189:3306/24901 |
2 |
8G |
10000Mb/s |
mysql-2 |
CentOS7.3 |
5.7.18 Community |
10.45.81.190:3306/24901 |
2 |
8G |
10000Mb/s |
mysql3 |
CentOS7.3 |
5.7.18 Community |
10.45.81.191:3306/24901 |
2 |
8G |
10000Mb/s |
测试环境主机为虚拟机
才用RPM包安装模式
配置my.cnf(mgr插件必要参数,省略了其他常用配置)
transaction_write_set_extraction=XXHASH64 #must uuid ,uuidgen can generate loose-group_replication_group_name="5ba6fb30-6481-4fd7-bfab-cb93cc9ec51f" loose-group_replication_start_on_boot=off loose-group_replication_local_address= "10.45.81.189:24901" loose-group_replication_group_seeds= "10.45.81.189:24901,10.45.81.190:24901,10.45.81.191:24901" loose-group_replication_bootstrap_group= off #multi master configuratio #loose-group_replication_single_primary_mode=OFF #loose-group_replication_enforce_update_everywhere_checks=ON |
初始化
#mysqld --initialize --user=mysql |
从日志中捞取密码:gF:PNpt+K6&S
修改/usr/lib/systemd/system/mysqld.service文件
LimitNOFILE = 5000=>LimitNOFILE = 10240(service 启动时候mysqld日志会告警 Changedlimits: max_open_files: 5000 (requested 10240))
#systemctl daemon-reload #service mysqld start |
$mysql -uroot -S /home/mysql5.7/data/mysql.sock -p mysql>alter user root@'localhost' identified by ''; mysql>flush privileges; mysql>create user root@'%' identified by 'root'; mysql>flush privileges; |
--安装mgr插件:
mysql>use mysql; mysql>INSTALL PLUGIN group_replication SONAME 'group_replication.so'; mysql>show plugins;(这边可以发现在最后一行已经安装成功并且active) |
--配置复制链路和用户--
mysql> SET SQL_LOG_BIN=0; mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'rpl_pass'; mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; mysql> FLUSH PRIVILEGES; mysql> SET SQL_LOG_BIN=1; |
--复制链路必须通过group_replication_recovery这个channel--
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery'; |
--初始化mgr
mysql>SET GLOBAL group_replication_bootstrap_group=ON; mysql>START GROUP_REPLICATION; mysql>SET GLOBAL group_replication_bootstrap_group=OFF; |
--确认启动成功--
mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 057ddcb0-5d38-11e7-9d42-0050568d984a | mysql-1 | 3306 | ONLINE | +---------------------------+--------------------------------------+-------------+-------------+--------------+
|
按照上述步骤增加其他2个节点,SET GLOBALgroup_replication_bootstrap_group=off无需开启。(以上内容仅测试MGR配置参数,不能单纯用于生产)
Single-Primary |
Test Case |
PASS/FAIL |
|
1.primry mysqld crash (no replication lag) |
PASS |
2.primary crash (no replication lag) |
PASS |
|
3.one slave crash(no replication lag) |
PASS |
|
4.two nodes crash(no replication lag) |
PASS |
|
5. two nodes crashed involuntarily (no replication lag) |
PASS |
|
6.primry mysqld crash (replication lag) |
PASS |
|
7. primary crash(replication lag) |
PASS |
|
8.recovery after all mgr nodes crash |
PASS |
|
9. Primary Network timeout to the others |
PASS |
|
10.Destructive Test |
PASS |
|
Multi-Primary |
1.one node crash (no replication lag) |
PASS |
2.two nodes crash(no replication lag) |
PASS |
|
3. two nodes crashed involuntarily |
PASS |
|
4.one node crash(replication lag) |
PASS |
|
5. two nodes crash(replication lag) |
PASS |
|
6.recovery after all mgr nodes crash |
FAILED |
|
7.One Node Network timeout to the others
|
PASS |
测试用例名称 |
1.主节点mysqld进程 crash(没有延迟) |
测试目的 |
确认主节点进程实例crash,MGR是否会正常切换主节点 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary
测试过程: 1. 在系统正常情况下无延迟情况下 2. Kill -9 mysql-1 节点(primary)
|
通过准则 |
正常切换 |
测试结果 |
Primary 正常切换到了mysql-2 |
备注 |
|
测试用例名称 |
2.主节点主机crash(没有延迟) |
测试目的 |
确认主机crash,MGR是否会正常切换主节点 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary
测试过程: 1. 确认系统正常运行没有延迟 2. reboot mysql-1(primary)
|
通过准则 |
主节点正常切换 |
测试结果 |
通过,Primary切换到了mysql-2上 |
备注 |
|
测试用例名称 |
3.一个从节点crash(没有延迟) |
测试目的 |
确认主节点状态是否正常 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary
测试过程: 1. 确认系统正常运行没有延迟 2. reboot mysql-2
|
通过准则 |
主节点可以正常对外提供读写,系统对外没明显异常变化 |
测试结果 |
通过 |
备注 |
|
测试用例名称 |
4.2个从节点 crash(没有延迟) |
测试目的 |
确认主节点是否能对外提供读写,状态是否正常 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary
测试过程: 1. 确认系统正常运行没有延迟 2. reboot mysql-2,mysql-3主机
|
通过准则 |
可以对外提供读写 |
测试结果 |
通过,外部可以读写 |
备注 |
参见官方文档17.1.3.3 Fault-tolerance描述In practice this means that to tolerate one failure the group must have three servers in it. As such if |
测试用例名称 |
4.2个从节点 crash(没有延迟) |
测试目的 |
确认主节点是否能对外提供读写,状态是否正常 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary
测试过程: 3. 确认系统正常运行没有延迟 4. Vsphere管理界面关闭电源 mysql-2,mysql-3主机
|
通过准则 |
剩余唯一节点不可写 |
测试结果 |
通过,外部不可以写 |
备注 |
参见官方文档17.1.3.3 Fault-tolerance描述In practice this means that to tolerate one failure the group must have three servers in it. As such if |
测试用例名称 |
5.主节点mysqld进程 crash(复制延迟) |
测试目的 |
确认复制延迟情况下主节点crash后,从节点是否恢复到主节点crash瞬间的数据后才切换角色 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary sysbench测试工具 测试过程: 1. 使用sysbench压测mysql-1 2. 查询执行事务设置队列长度迫使2个seconady存在较长时间延迟 3. Kill -9 mysql-1(primary) 4. 确认集群primary状态
|
通过准则 |
能正常切换选出新primary节点 |
测试结果 |
通过,能选出新的primary |
备注 |
此处存在一个配置问题,如果说配置不当导致延迟非常严重情况下会导致读取不一致的情况。 |
测试用例名称 |
6.主节点 crash(复制延迟) |
测试目的 |
确认复制延迟情况下主节点crash后,从节点是否恢复到主节点crash瞬间的数据后才切换角色 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary sysbench测试工具 测试过程: 1. 使用sysbench压测mysql-1 2. 查询执行事务设置队列长度迫使2个seconady存在较长时间延迟 3. Reboot mysql-1(primary) 4. 确认集群primary状态
|
通过准则 |
能正常切换选出新primary节点 |
测试结果 |
通过 |
备注 |
此处存在一个配置问题,如果说配置不当导致延迟非常严重情况下会导致读取不一致的情况 |
测试用例名称 |
7.三个节点在复制存在延迟情况下 都crash场景 |
测试目的 |
确任数据一致性 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary sysbench测试工具
测试过程: 1. 使用sysbench压测mysql-1 2. 查询执行事务设置队列长度迫使2个seconady存在较长时间延迟 3. Reboot mysql-1(primary); Reboot mysql-2(secondary); Reboot mysql-3(secondary) 4. 启动3个节点,取gtid最大的节点做为bootstrap主机 5. 确认MGR状态
|
通过准则 |
MGR状态2个recovery转换成online,最终3个online,且gtid一致,检查个表对比记录数一致 |
测试结果 |
通过 |
备注 |
|
测试用例名称 |
8.主节点和其他2个节点网络超时 |
测试目的 |
确认网络超时场景角色是否正常变化 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary 每个节点操作set global group_replication_unreachable_majority_timeout=10; 测试过程: 1. 使用sysbench压测mysql-1 2. 在mysql-2和mysql-3上执行iptables -I INPUT -s 10.45.81.189 -j DROP 3. 确认sysbench是否能继续读写 4. 确认primary是否发生迁移 5. 去除网络分区从新加入MGR 6. 确认数据是否一致
|
通过准则 |
当发生网络分区情况,少于1/2 members的节点不会对外提供写操作,primary迁移 |
测试结果 |
通过mysql-1 MGR状态为ERROR,PRIMARY迁移到mysql-2上 |
备注 |
这里当发生网络分区时虽然mysql-1节点不可写,但是sysbench客户端没报错一直写入虽然tps是0,可能中间件在判断角色异常时需要注意 |
测试用例名称 |
9.删除数据,清理binlog下恢复方式 |
测试目的 |
确认新节点加入已存在节点下是否可以直接同步 |
测试方法
|
预置条件: mysql-1 Primary mysql-2 secondary mysql-3 secondary
测试过程: 1. mysql-1purge binary logs to 'mysql-bin.000021'; 2. mysql-2退出mgr删除数据,并reset master 3. mysql-2启动加入mgr命令
|
通过准则 |
能自动全库恢复,或者其他方式数据同步基于例如binlog |
测试结果 |
通过 |
备注 |
mysql的恢复过程依旧是依赖于binlog来完成,如果新加节点或者替换节点需要从备份中先恢复日志到gtid存在于binlog中. 2017-07-27T08:46:00.935860Z 139 [ERROR] Error reading packet from server for channel 'group_replication_recovery': The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires. (server_errno=1236) 2017-07-27T08:46:00.935916Z 139 [ERROR] Slave I/O for channel 'group_replication_recovery': Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.', Error_code: 1236 2017-07-27T08:46:00.935928Z 139 [Note] Slave I/O thread exiting for channel 'group_replication_recovery', read up to log 'FIRST', position 4 2017-07-27T08:46:00.936159Z 119 [Note] Plugin group_replication reported: 'Terminating existing group replication donor connection and purging the corresponding logs.' 2017-07-27T08:46:00.937460Z 140 [Note] Error reading relay log event for channel 'group_replication_recovery': slave SQL thread was killed 2017-07-27T08:46:00.942109Z 119 [Note] 'CHANGE MASTER TO FOR CHANNEL 'group_replication_recovery' executed'. Previous state master_host='mysql-2', master_port= 3306, master_log_file='', master_log_pos= 4, master_bind=''. New state master_host=' 2017-07-27T08:46:00.949483Z 119 [ERROR] Plugin group_replication reported: 'Maximum number of retries when trying to connect to a donor reached. Aborting group replication recovery.'
|
测试用例名称 |
1.任意一个节点crash (没有延迟) |
测试目的 |
确认其他2个节点读写不会受到影响 |
测试方法
|
预置条件: mysql-1 Master mysql-2 Master mysql-3 Master
测试过程: 1. 在系统正常情况下无延迟情况下 2. Kill -9 mysql-1 节点
|
通过准则 |
其他节点不受影响 |
测试结果 |
通过 |
备注 |
|
测试用例名称 |
2.任意2个节点 crash(没有延迟) |
测试目的 |
确认2个主机crash场景下剩余一个节点状态是否正常 |
测试方法
|
预置条件: mysql-1 Master mysql-2 Master mysql-3 Master
测试过程: 1. reboot mysql-1,myqsl-2 2. mysql-3尝试写入数据
|
通过准则 |
Mysql-3可以写入 |
测试结果 |
通过 |
备注 |
|
测试用例名称 |
2.任意2个节点 crash(没有延迟) 异常断电 |
测试目的 |
确认2个主机crash场景下剩余一个节点状态是否正常 |
测试方法
|
mysql-1 Master mysql-2 Master mysql-3 Master group_replication_flow_control_applier_threshold=25000 group_replication_flow_control_certifier_threshold=25000 set global group_replication_unreachable_majority_timeout=15;或者0 测试过程: 1. sysbench-1 压mysql-1 db=test1 table=sbtest 2. sysbench-2 压mysql-2 db=test2 table=sbtest 3. sysbench-3 压mysql-3 db=test3 table=sbtest 4. 上面三个同时进行压力测试 5. 登录各个库比较插入表和复制表是否存在延迟 6. 存在延迟后依次重启电源2个节点 7. 确认剩余节点是否可写 8. 确认恢复后从新加入MGR
|
通过准则 |
剩余一个节点不可写,节点恢复后可恢复一致性 |
测试结果 |
通过 |
备注 |
group_replication_unreachable_majority_timeout=15和=0结果是不一样的,=0所有的操作都被block住必须手动stop mgr才会回滚,=15则timeout时间到后会主动切换状态为ERROR为只读状态,不可写入数据。 |
测试用例名称 |
3. 复制延迟情况下任意一个节点crash |
测试目的 |
确认复制延迟情况下任意一个节点crash复制组是否会受影响 |
测试方法
|
预置条件: mysql-1 Master mysql-2 Master mysql-3 Master group_replication_flow_control_applier_threshold=25000 group_replication_flow_control_certifier_threshold=25000 测试过程: 9. sysbench-1 压mysql-1 db=test1 table=sbtest 10. sysbench-2 压mysql-2 db=test2 table=sbtest 11. sysbench-3 压mysql-3 db=test3 table=sbtest 12. 上面三个同时进行压力测试 13. 登录各个库比较插入表和复制表是否存在延迟 14. 存在延迟后reboot其中任意1个主机 15. 恢复后从新加入MGR
|
通过准则 |
从新加入节点后,数据一致性不受影响。剩余主机读写不受影响 |
测试结果 |
通过 |
备注 |
实际延迟情况下此时读写分离存在数据不一致问题,这种状态需要根据实际业务情况下可以动态调整参数解决,但是代价是降低系统吞吐量,同时也降低了系统恢复时间 |
测试用例名称 |
4.复制延迟情况下2个节点crash |
测试目的 |
确认复制延迟时候2节点crash,复制组状态 |
测试方法
|
预置条件: mysql-1 Master mysql-2 Master mysql-3 Master group_replication_flow_control_applier_threshold=25000 group_replication_flow_control_certifier_threshold=25000 默认值 测试过程: 1. sysbench-1 压mysql-1 db=test1 table=sbtest 2. sysbench-2 压mysql-2 db=test2 table=sbtest 3. sysbench-3 压mysql-3 db=test3 table=sbtest 4. 上面三个同时进行压力测试 5. 登录各个库比较插入表和复制表是否存在延迟 6. 存在延迟后reboot其中任意2个主机 7. 恢复后从新加入MGR
|
通过准则 |
2个节点reboot后,剩下节点任然可写;2个节点从新启动后任然可以加入到原MGR中恢复数据一致性 |
测试结果 |
通过,可以从新接入MGR,数据一致,但是由于磁盘性能导致恢复时间比较长 |
备注 |
3master和单master性能在此种情况下是一致的。当由于异常断电involuntarily导致的2节点crash,数据一致性会得到保证,如果是人为reboot,则数据一致性会可能受的破坏。 |
测试用例名称 |
5. 存在延迟的情况下3个节点都crash |
测试目的 |
确认事务一致性是否可以正常恢复 |
测试方法
|
预置条件: mysql-1 Master mysql-2 Master mysql-3 Master group_replication_flow_control_applier_threshold=25000 group_replication_flow_control_certifier_threshold=25000
测试过程: 1. sysbench-1 压mysql-1 db=test1 table=sbtest 2. sysbench-2 压mysql-2 db=test2 table=sbtest 3. sysbench-3 压mysql-3 db=test3 table=sbtest 4. 上面三个同时进行压力测试 5. 登录各个库比较插入表和复制表是否存在延迟 6. 存在延迟后依次reboot 其中3个主机/直接同时重启三个机器 7. 恢复后从新加入MGR
|
通过准则 |
数据一致,可以正常启动 |
测试结果 |
不通过,数据不一致。无法从新组成MGR |
备注 |
启动时确认从gtid最大的主机做为bootstrap |
测试用例名称 |
6.任意一个节点到其他2个节点网络超时 |
测试目的 |
确认网络超时(分区)场景下 |
测试方法
|
预置条件: mysql-1 Master mysql-2 Master mysql-3 Master 每个节点操作set global group_replication_unreachable_majority_timeout=10; 测试过程: 1. 使用sysbench压测mysql-1 2. 在mysql-2和mysql-3上执行iptables -I INPUT -s 10.45.81.189 -j DROP 3. 确认sysbench是否能继续读写 4. 确认primary是否发生迁移 5. 去除网络分区从新加入MGR 6. 确认数据是否一致
|
通过准则 |
当发生网络分区情况,少于1/2 members的分区不会对外提供写操作,数据一致性得到保证 |
测试结果 |
通过 |
备注 |
|
1. Single-Master情况下除去人为的kill-9 ,service stop mysqld,或者reboot,意外断电导致的3节点MGR中2节点crash,剩余节点会变成只读。从而保证了全局的数据一致性,也就是说在一个节点crash时候必须要及时进行恢复操作,否则影响生产。
2. group_replication_flow_control_applier_threshold=25000,group_replication_flow_control_certifier_threshold=25000这连个参数会影响到数据的延迟度,MGR的性能和MGR得到恢复时间需要,带业务测试去优化设置这个参数(可以动态调整)。
3. MGR中对磁盘的性能要求比较高尤其是2个secondary节点的磁盘压力比priamry要高
4. 在恢复过程中需要确保binary的完整性。通常建议一天一次增量备份xtrabackup
5. Multi-Master情况下遇见一个问题,不确定是否bug
2个sysbench同时插了一个库一张表导致了回滚报错后在mysql-1上truncate了这个表
FATAL: mysql_drv_query() returned error 3101 (Plugin instructed the server to rollback the current transaction.) for query 'INSERT INTO sbtest1 (id, k, c, pad) VALUES (0, 57039, '38882197345-24142090551-37634413186-05617166763-63557711110-08431531461-06777598914-80364280086-53479402835-10264036621', '98878126092-94770377880-38767081253-60554061330-48907630932')' FATAL: `thread_run' function failed: ../share/sysbench/oltp_insert.lua:47: SQL error, errno = 3101, state = 'HY000': Plugin instructed the server to rollback the current transaction. |
但是最终回滚报错的客户端写入的mysql-3上最终表里数据确存在数据。导致数据存在不一致情况。
6. 在允许延迟情况下如果上节点同时crash,会导致数据不可逆无法恢复,且备份时不易备份(因为各个节点都存在延迟)
注:暂不推荐使用MGR的 Multi-Master的模式对外提供服务。
1.必须binlog-checksum=NONE
2.不支持gap锁,建议使用Read-Commit(这点集成默认推荐使用RC模式不冲突)
3.MGR没有考虑到表锁情况,个人目前感觉这点主要体现在多主情况,或者单主模式下Primary lock table后,主从切换表锁失效问题。
4.不支持 Savepoints
5.不支持事务级别SERIALIZABLE
6.不支持同一对象上的DDL和DML操作(Multi-Master情况下)
7.不支持外键级联约束限制(Multi-Master情况下)
避免大事务