MySQL 5.5+ 主从同步 Semisync Replication

Posted 代码与远方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 5.5+ 主从同步 Semisync Replication相关的知识,希望对你有一定的参考价值。

mysql5.5 semi-sync安装维护



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。

主库上,新增如下参数:

$vi my.cnf
...
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=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是否有超时失败过,该计数器则记录了这样的失败次数。

 

参考:
http://www.orczhou.com/index.php/2011/06/mysql-5-5-semi-sync-replication-setup-config/
http://www.mysqlops.com/2011/10/24/mysql-semi-replicatio.html
http://code.google.com/p/google-mysql-tools/wiki/SemiSyncReplication
http://www.orczhou.com/index.php/2011/07/why-and-how-mysql-5-5-semi-sync-replication/



来源:http://blog.csdn.NET/wyzxg/article/details/8487953 



【MySQL】Semisynchronous Replication 概述 



前言 


    MySQL 5.5版本之前默认的复制是异步(Asynchronous )模式的, MySQL 5.5 以plugins的方式提供了Semisynchronous Replication 模式。在介绍 semi sync 之前,我们先了解:半同步 Asynchronous 和 同步 Synchronous 。


异步复制模式

    主库将已经提交的事务event 写入binlog后,即返回成功给app,该模式下并不保证任何已经提交的事务会传递到任何slave并被成功应用。

全同步复制模式。

    当主库提交一个事务 event,主库会等待该事务被传递到所有的slave上,且所有slave applay 该事务/event 通知主库之后,才会返回回话,事务已经成功。

   从定义中可以看出 异步模式不能保证数据的安全性,因为它不等待主库提交的事务在slave 上落盘,而全同步模式 由于要等待所有的slave 确认已提交事务成功被应用,如此则会带来事务处理上的延时。semi sync 则取了一个比较折中的方式,确保已提交的事务必须存在于至少两个机器(主库和任一备库
),立即返回给客户端 事务成功。


一 Semisynchronous Replication 定义

  
 Semisynchronous Replication模式下,在主库上提交一个事务/event,它会等待至少一个slave通知主库,slave 已经接收到传递过来的events并写入relay log,才返回给回话层 写入成功,或者直到传送日志发生超时。


      

 


二 优缺点


   
优点:当事务返回成功给客户端时,则事务至少在两台机器上存在,增强数据安全性。相比异步模式和全同步模式,是一种折中。

    缺点:半同步的确会对数据库性能有一定影响,因为事务的提交必须等待slave 反馈。性能损耗取决于tcp/IP 网络传输时间,也即传输已提交事务和等待slave 反馈已经接收事务的时间。


三 MySQL 半同步的特性


    1 当slave 连接主库时,它会告知主库它是不是semi sync 模式。

    2 如果主库启用了semi sync模式,且至少一个slave 也启用了semi sync模式,一个在主库操作事务的进程在事务提交之后,且至少一个slave 通知主库成功接收所有事务之前,该进程会处于blocks 等待状态或者直到超时发生。
    3 当且仅当传递过来的events 传递到slave,被写入relay log,刷新到磁盘才会通知主库完成。
    4 Semisynchronous replication 必须在主备两端都同时启用,否则任何一个未设置,主备之间的复制模式将转变为异步复制模式。
    5 当所有slave 在(rpl_semi_sync_master_timeout的默认值)时间内未返回给主库成功接收event,主备之间就会变回原来的异步状态。

 其中关于第二点 MySQL 5.7 已经做了优化,由ack Collector (Col) thread 等待备库的成功接收事务的通知,这点后续会做详细介绍--《5.7 Semisync replication 增强》。

四 异常处理
   当备库Crash时,主库会在某次等待超时后,关闭Semi-sync的特性,降级为普通的异步复制,这种情况比较简单。

MySQL的 error.log 会提示:
    

  1. 140523 22:26:00 [Warning] Timeout waiting for reply of binlog (file: mysql-bin.000002, pos: 465893519), semi-sync up to file , position 0.

  2. 140523 22:26:00 [Note] Semi-sync replication switched OFF.

    比较难以处理的情况是:当主机/主库Crash时,可能存在一些事务已经在主库提交,但是还没有来的及传给任何备库,也即这些事务都是没有返回给客户端的,所以发起事务的客户端并不知道这个事务是否已经完成--"墙头事务"。这时,如果客户端不做切换,只是等Crash的主库恢复后,继续在主库进行操作,客户端会发现前面的"墙头事务"都已经完成,可以继续进行后续的业务处理;另一种情况,如果客户端Failover到备库上,客户端会发现前面的“墙头事务”都没有成功,则需要重新做这些事务,然后继续进行后续的业务处理,其实此时主备是不一致的,需要通过主备数据校验来检查哪一个库是正确的,然后进行修复。
     

五 小结


   总之相比于MySQL 5.5 版本之前的异步复制模式 semi sync 已经有了很大的进步,增强了数据的安全性,以安全换一定的性能损耗还是可以接受的。后续会介绍如何安装和使用semi sync。



六 推荐文章
[1] Semisynchronous replication
[2] Semisync separate acks collector
[3] MySQL半同步Semi-sync原理介绍
[4] SemiSync Replication Design  



来源:http://blog.itpub.net/22664653/viewspace-1168839/ 



【MySQL】5.7版本 Semisync Replication 增强 



一 前言


前文 介绍了5.5/5.6 版本的MySQL semi sync 基础原理和配置,随着MySQL 5.7 的发布,新版本的MySQL修复了semi sync 的一些bug 并且增强了功能。


  1. 支持发送binlog和接受ack的异步化;

  2. 支持在事务commit前等待ACK;

  3. 在server层判断备库是否要求半同步以减少Plugin锁冲突;

  4. 解除binlog dump线程和lock_log的冲突等等。

本文重点分析 第1,2个改进项,因为原来的模式的确会影响系统的tps,新的异步模式可以提高半同步模式下的系统事务处理能力。



二 优化


1 支持发送binlog和接受ack的异步化
通过前面的介绍,我们知道Semisynchronous Replication模式下,app在主库上提交一个事务/event,MySQL将每个事务写入binary并且同步到到slave ,master会等待至少一个slave通知:slave 已经接收到传过来的events并写入relay log,才返回给回话层 写入成功,或者直到传送日志发生超时,系统自动将为异步复制模式。


整体流程的逻辑图




5.5 版本semi sync 设计的缺点:


    从原理以及上图来看,旧版本的semi sync 受限于dump thread ,原因是dump thread 承担了两份不同且又十分频繁的任务:传送binlog 给slave ,还需要等待slave反馈信息,而且这两个任务是串行的,dump thread 必须等待 slave 返回之后才会传送下一个 events 事务。dump thread 已然成为整个半同步提高性能的瓶颈在高并发业务场景下,这样的机制会影响数据库整体的TPS .



为了解决上述问题,在5.7.4版本的semi sync 框架中,独立出一个 ack collector thread ,专门用于接收slave 的反馈信息。这样master 上有两个进程独立工作,可以同时发送binlog 到slave ,和接收slave的反馈。整体流程的逻辑图




大体的实现思路是:
备库IO线程使用TCP协议和主库交互,读写socket可以同时进行,在开启主库semisync时,启动一个后台线程,使用select监听备库连接socket;
dump线程不再等待备库ACK;在ack reciver线程等待ACK时,dump线程还能继续发送下一组group commit的binlog,进而提升TPS.


2 支持在事务commit前等待ACK;


   新版本的semi sync 增加了rpl_semi_sync_master_wait_point参数 来控制半同步模式下 主库在返回给会话事务成功之前提交事务的方式。
该参数有两个值:
AFTER_SYNC (默认值):
master 将每个事务写入binlog ,传递到slave,并且刷新到磁盘。master等待slave 反馈接收到事务并刷新到磁盘。一旦接到slave反馈,master在主库提交事务并且返回结果给会话。
 在AFTER_SYNC模式下,所有的客户端在同一时刻查看已经提交的数据。假如发生主库crash,所有在主库上已经提交的事务已经同步到slave并记录到relay log。此时切换到从库,可以保障最小的数据损失。

AFTER_COMMIT: 
master 将每个事务写入binlog ,传递到slave 刷新到磁盘(relay log),然后在主库提交事务。master在提交事务后等待slave 反馈接收到事务并刷新到磁盘。一旦接到slave反馈,master将结果反馈给客户端。

在AFTER_COMMIT模式下,如果slave 没有应用日志,此时master crash,系统failover到slave,app将发现数据出现不一致,在master提交而slave 没有应用。



三 推荐阅读

注:最后三个来自于MySQL replication 开发小组的blog,需要翻墙,请自备梯子。
[1] 5.7 Semisynchronous Replication

[2] loss-less-semi-synchronous-replication

MySQL 5.7 修改了半同步中主库提交的事务的顺序,after sync 模式避免了幻读发生。
[3] enforced-semi-synchronous-replication
MySQL 5.7 半同步增强,增加 rpl_semi_sync_master_wait_slave_count 参数控制主库接收多少个slave 写事务成功反馈 才返回 成功给客户端 。
[4] faster-semisync-replication
修改原来有dump thread 发送event和接收slave ack 模式,独立出 单独 接收slave 返回 ack的进程,提高半同步模式的tps 。



来源:http://blog.itpub.Net/22664653/viewspace-1183057/


以上是关于MySQL 5.5+ 主从同步 Semisync Replication的主要内容,如果未能解决你的问题,请参考以下文章

mysql5.7 开启增强半同步复制

MySQL.半同步复制

mysql主从复制--mysql-5.5异步半同步配置

MySQL-5.5之主从复制 + 半同步

简述mysql半同步复制—semisync

centos7下mysql5.6.30配置单机多实例主从半同步复制