mysql5.5 semi-sync replication 安装维护
mysql的replication协议是异步的,虽然异步效率、性能很好,但是却无法保证主从数据一致性(如果master crash,已经commit的事务不会被传送到任何的slave上),从mysql5.5之后,mysql为了保证主从库数据一致性,引进了semi-sync功能,semi-sync意思是MASTER只需要接收到其中一台SLAVE的返回信息,就会commit;否则需等待直至切换成异步再提交。
优点:
当事务返回客户端成功后,则日志一定在至少两台主机上存在。
MySQL的Semi-sync适合小事务,且两台主机的延迟又较小,则Semi-sync可以实现在性能很小损失的情况下的零数据丢失。
缺点:
完成单个事务增加了额外的等待延迟,延迟的大小取决于网络的好坏。
Semi-sync不是分布式事务,主库会在自己完成事务后,等待备库接收事务日志(网易已经修改源码,使其在同一事务里)
备库Crash时,主库会在某次等待超时后,关闭Semi-sync的特性,降级为普通的异步复制,这种情况比较简单。
主库Crash后,那么可能存在一些事务已经在主库Commit,但是还没有传给任何备库,我们姑且称这类事务为”墙头事务”。”墙头事务”都是没有返回给客户端的,所以发起事务的客户端并不知道这个事务是否已经完成。这时,如果客户端不做切换,只是等Crash的主库恢复后,继续在主库进行操作,客户端会发现前面的”墙头事务”都已经完成,可以继续进行后续的业务处理;另一种情况,如果客户端Failover到备库上,客户端会发现前面的“墙头事务”都没有成功,则需要重新做这些事务,然后继续进行后续的业务处理。
安装
在主库安装semisync_master插件:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’; //linux
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.dll’; //windows
在备库安装semisync_slave插件
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’; //linux
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;//windows
在初次安装插件后,MySQL会将该插件记录到系统表mysql.plugin中,下次启动时系统则会自动加载该插件了,无需再次执行上面的命令。
简要安装如下
Master端的安装过程
1.INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;
2.SHOW VARIABLES LIKE ‘rpl_semi_sync_master_enabled’ 值为ON,表示开启;否则检查失败原因
3.SET GLOBAL rpl_semi_sync_master_timeout=100000(利于观察);
4.SET GLOBAL rpl_semi_sync_master_wait_no_slave=1(是默认值,表示即使没有SLAVE也会等待过期时间结束)
Slave端的安装过程
1.INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;
2.SHOW VARIABLES LIKE ‘rpl_semi_sync_slave_enabled’ 值为ON,表示开启;否则失败检查原因
如果要启用半同步功能,在主备库的配置文件my.cnf还需要新增如下记录来打开semi-sync。
主库上,新增如下参数:
vimy.cnf…rplsemisyncmasterenabled=1rplsemisyncmastertimeout=1000…备库上新增:
vi my.cnf
…
rpl_semi_sync_slave_enabled=1
…
如果考虑主备切换,就需要两个插件在master/slave上都安装,在配置文件my.cnf主备参数都需要添加
主备在启动后,且slave线程开始dump主库的日志后,Semi-sync Replication就会开启,上面的配置(rpl_semi_sync_master_timeout=1000)表示主库在某
次事务中,如果等待时间超过1000毫秒,那么则降级为普通模式,不再等待备库。如果主库再次探测到,备库恢复了,则会自动再次回到Semi-sync状态。
主备库上的参数
mysql> show variables like ‘%rpl_semi%’;
+————————————+——-+
| Variable_name | Value |
+————————————+——-+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 1000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+————————————+——-+
7 rows in set (0.00 sec)
从库上参数:
mysql> show variables like ‘%rpl_semi%’;
+————————————+——-+
| Variable_name | Value |
+————————————+——-+
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+————————————+——-+
6 rows in set (0.00 sec)
mysql>
如果在master上安装两个插件,master的参数如下(slave也一样):
mysql> show variables like ‘%rpl_semi%’;
+————————————+——-+
| Variable_name | Value |
+————————————+——-+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 1000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+————————————+——-+
6 rows in set (0.00 sec)
mysql>
参数说明:
rpl_semi_sync_master_timeout=1000 :表示主库在某次事务中,如果等待时间超过1000毫秒,那么则降级为普通模式,不再等待备库。
如果主库再次探测到,备库恢复了,则会自动再次回到Semi-sync状态,在测试时,可以设置大些,利于观察
rpl_semi_sync_master_wait_no_slave=1:表示即使没有SLAVE也会等待过期时间结束,是默认值,
这两个变量可以在线设置,但如果不写在my.cnf中,数据库重启参数就恢复默认值了
SET GLOBAL rpl_semi_sync_master_timeout=100000
SET GLOBAL rpl_semi_sync_master_wait_no_slave=1
验证master/slave是否启用semi-sync
检查master端semi-sync安装之后是否启用(rpl_semi_sync_master_enabled如果值为ON,表示开启;否则检查失败原因)
mysql> show variables like ‘%rpl_semi_sync_master_enabled%’;
+——————————+——-+
| Variable_name | Value |
+——————————+——-+
| rpl_semi_sync_master_enabled | ON |
+——————————+——-+
1 row in set (0.00 sec)
检查slave端semi-sync安装之后是否启用(rpl_semi_sync_slave_enabled如果值为ON,表示开启;否则检查失败原因)
mysql> show variables like ‘%rpl_semi_sync_slave_enabled%’;
+—————————–+——-+
| Variable_name | Value |
+—————————–+——-+
| rpl_semi_sync_slave_enabled | ON |
+—————————–+——-+
1 row in set (0.00 sec)
mysql>
查看master/slave的semi-sync运行状态
在slave上查看semi-sync是否开启
mysql> show status like ‘%rpl_semi%’;
+——————————————–+——-+
| Variable_name | Value |
+——————————————–+——-+
| Rpl_semi_sync_slave_status | ON |
+——————————————–+——-+
15 rows in set (0.00 sec)
mysql>
在master上查看semi-sync是否开启
mysql> show status like ‘%rpl_semi%’;
+——————————————–+——-+
| Variable_name | Value |
+——————————————–+——-+
| Rpl_semi_sync_master_clients | 2 | #有多少个Semi-sync的备库
| Rpl_semi_sync_master_net_avg_wait_time | 1209 | #事务提交后,等待备库响应的平均时间
| Rpl_semi_sync_master_net_wait_time | 213811529 | #等待网络响应的总次数
| Rpl_semi_sync_master_net_waits | 176714 | #总的网络等待时间
| Rpl_semi_sync_master_no_times | 0 | #一共有几次从Semi-sync跌回普通状态
| Rpl_semi_sync_master_no_tx | 0 | #备库未及时响应的事务数
| Rpl_semi_sync_master_status | ON | #主库上Semi-sync是否正常开启
| Rpl_semi_sync_master_timefunc_failures | 0 | #时间函数未正常工作的次数
| Rpl_semi_sync_master_tx_avg_wait_time | 1618 | #开启Semi-sync,事务返回需要等待的平均时间
| Rpl_semi_sync_master_tx_wait_time | 156225399 | #事务等待备库响应的总时间
| Rpl_semi_sync_master_tx_waits | 96501 | #事务等待备库响应的总次数
| Rpl_semi_sync_master_wait_pos_backtraverse | 1006 | #改变当前等待最小二进制日志的次数
| Rpl_semi_sync_master_wait_sessions | 0 | #当前有几个线程在等备库响应
| Rpl_semi_sync_master_yes_tx | 92171 | #Semi-sync模式下,成功的事务数
+——————————————–+——-+
15 rows in set (0.00 sec)
mysql>
master状态参数说明
Rpl_semi_sync_master_tx_avg_wait_time:事务因开启Semi_sync,平均需要额外等待的时间
Rpl_semi_sync_master_net_avg_wait_time:事务进入等待队列后,网络平均等待时间
依据上面两个状态值可以知道,Semi-sync的网络消耗有多大,给某个事务带来的额外的消耗有多大。
Rpl_semi_sync_master_status: 则表示当前Semi-sync是否正常工作。
Rpl_semi_sync_master_no_times:表示可以知道一段时间内,Semi-sync是否有超时失败过,该计数器则记录了这样的失败次数。