mysql半同步配置
mysql集群是一主双从的三节点集群,使用orchestrator管理该集群。
使用半同步方式配置集群,主节点写需要等到一个从节点接收到relay-log并返回成功ack,才能成功完成写操作。
配置用户
create user repl@'%' identified with mysql_native_password by '123';
grant replication slave on *.* to repl@'%';
repl用户专门用来做数据复制。
配置主从
从节点上执行
:
stop slave;
CHANGE MASTER TO MASTER_HOST='MasterIP', MASTER_USER='repl', MASTER_PORT=3306,master_auto_position=1,MASTER_RETRY_COUNT=86400;
start slave;
配置插件
主节点执行
:
mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
[要保证/usr/local/mysql/lib/plugin/目录下有semisync_master.so文件 (默认编译安装后就有)]
如果要卸载(前提是要关闭半同步复制功能),就执行
mysql> UNINSTALL PLUGIN rpl_semi_sync_master;
从节点执行
:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
[要保证/usr/local/mysql/lib/plugin/目录下有semisync_slave.so文件 (默认编译安装后就有)]
如果要卸载(前提是要关闭半同步复制功能),就执行
mysql> UNINSTALL PLUGIN rpl_semi_sync_slave;
配置参数
主节点关键参数:
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_wait_for_slave_count=1
rpl_semi_sync_master_wait_no_slave=1
rpl_semi_sync_master_timeout=60
rpl_semi_sync_slave_enabled=0(这个在主节点上是0是1好像没什么关系T_T)
说明:rpl_semi_sync_master_enabled要设置为1,代表这是主节点的角色
rpl_semi_sync_master_wait_for_slave_count设置为1,代表一个节点同步,一个节点异步,这样符合半同步实例的含义;
主节点、从节点可以观察的一些关键参数:
mysql>show global variables like "%sync%"; show global status like "%sync%";
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 60000 |
| rpl_semi_sync_master_wait_for_slave_count | 3 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
| rpl_semi_sync_slave_enabled | ON |
+-------------------------------------------+------------+
18 rows in set (0.00 sec)
+--------------------------------------------+----------+
| Variable_name | Value |
+--------------------------------------------+----------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+----------+
19 rows in set (0.00 sec)
【Rpl_semi_sync_master_clients】
:当前能够给与反馈的从库数量
【Rpl_semi_sync_master_status】
:on为半同步复制,off为异步复制
【Rpl_semi_sync_slave_status】
:动态调整rpl_semi_sync_slave_enabled=on,restart slave io thread才能让slave的Rpl_semi_sync_slave_status动态变化,进而让主库的Rpl_semi_sync_master_clients动态增减;
【rpl_semi_sync_master_wait_for_slave_count】
:
1.master提交后所需的应答数量!如果slave clients数量大于等于这个值,那么master会一路畅行无阻;如果低于这个值,master可能会在事务提交阶段发生一次超时等待,当等待超过参数(rpl_semi_sync_master_timeout)设定时,master就转为异步模式(原理见下一个参数)。
2.master将这个参数值作为标杆,用来和Rpl_semi_sync_master_clients参数做比较。
【rpl_semi_sync_master_wait_no_slave】
:
1.为OFF时,只要master发现Rpl_semi_sync_master_clients小于rpl_semi_sync_master_wait_for_slave_count,则master立即转为异步模式。
2.为ON时,空闲时间(无事务提交)里,即使master发现Rpl_semi_sync_master_clients小于rpl_semi_sync_master_wait_for_slave_count,也不会做任何调整。只要保证在事务超时之前,master收到大于等于rpl_semi_sync_master_wait_for_slave_count值的ACK应答数量,master就一直保持在半同步模式;如果在事务提交阶段(master等待ACK)超时,master才会转为异步模式。
故障发生
我们的配置是一主两从,半同步复制,rpl_semi_sync_master_wait_for_slave_count=1。
rpl_semi_sync_master_timeout=100000000000000(让主节点一直等,考虑到数据安全的问题)
使用ifdown关闭从节点rpl_semi_sync_slave_enabled=on的网卡,主节点写会一直卡住。
(这里说明一下,如果不是关网卡,而是关mysql服务,并不会出现这种情况,orchestrator会检测到该节点的mysql服务挂掉了,然后将另外一个节点的rpl_semi_sync_slave_enabled置为on,这样就不必等待rpl_semi_sync_master_timeout时间让主从复制退化成异步复制了。我们的初衷是一直保持半同步,这样数据至少存在两个点上,数据安全性比较高。)
故障原因
目前想到的是由于网卡关闭,该节点上的orchestrator并不能够将自己检测到的结果同步到其他点上,因此另外一个从节点也就接收不到修改rpl_semi_sync_slave_enabled这个参数的命令,所以就会一直等待下去。