从MySQL5.5开始,MySQL以插件的形式支持半同步复制。如何理解半同步呢?首先我们来看看异步,全同步的概念

一、三种同步

异步复制(Asynchronous replication)

MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

全同步复制(Fully synchronous replication)

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

半同步复制(Semisynchronous replication)

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

下面来看看半同步复制的原理图:

二、半同步复制的潜在问题

客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种

事务还没发送到从库上

此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。

事务已经发送到从库上

此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。

三、无数据丢失的半同步复制(无损半同步复制)

针对上述潜在问题,MySQL 5.7引入了一种新的半同步方案:Loss-Less半同步复制。

针对上面这个图,“Waiting Slave dump”被调整到“Storage Commit”之前。

当然,之前的半同步方案同样支持,MySQL 5.7.2引入了一个新的参数进行控制-rpl_semi_sync_master_wait_point

rpl_semi_sync_master_wait_point有两种取值:

AFTER_SYNC

这个即新的半同步方案,Waiting Slave dump在Storage Commit之前。

AFTER_COMMIT

老的半同步方案,如图所示。

四、半同步复制的安装部署

要想使用半同步复制,必须满足以下几个条件:

1. MySQL 5.5及以上版本

2. 变量have_dynamic_loading为YES

3. 异步复制已经存在

首先加载插件

因用户需执行INSTALL PLUGIN, SET GLOBAL, STOP SLAVE和START SLAVE操作,所以用户需有SUPER权限。

主:

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

从:

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

查看插件是否加载成功

有两种方式

1.

mysql> show plugins;

rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL  

2.

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';

+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
1 row in set (0.00 sec)

启动半同步复制

在安装完插件后,半同步复制默认是关闭的,这时需设置参数来开启半同步

主:

mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;

从:

mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;

以上的启动方式是在命令行操作,也可写在配置文件中。

主:

plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=1

从:

plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=1

在有的高可用架构下,master和slave需同时启动,以便在切换后能继续使用半同步复制

plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
rpl-semi-sync-master-enabled = 1
rpl-semi-sync-slave-enabled = 1

重启从上的IO线程

mysql> STOP SLAVE IO_THREAD;

mysql> START SLAVE IO_THREAD;

如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色。

这时候,主的error.log中会打印如下信息:

2016-08-05T10:03:40.104327Z 5 [Note] While initializing dump thread for slave with UUID , found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(4).
2016-08-05T10:03:40.111175Z 4 [Note] Stop asynchronous binlog_dump to slave (server_id: 2)
2016-08-05T10:03:40.119037Z 5 [Note] Start binlog_dump to master_thread_id(5) slave_server(2), pos(mysql-bin.000003, 621)
2016-08-05T10:03:40.119099Z 5 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 621)

查看半同步是否在运行

主:

mysql> show status like 'Rpl_semi_sync_master_status';

+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)

从:

mysql> show status like 'Rpl_semi_sync_slave_status';

+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.20 sec)

这两个变量常用来监控主从是否运行在半同步复制模式下。

至此,MySQL半同步复制搭建完毕~

五、事实上,半同步复制并不是严格意义上的半同步复制

当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。

下面来测试一下

该验证分为三个阶段

1. 在Slave执行stop slave之前,主的insert操作很快就能返回。

2. 在Slave执行stop slave后,主的insert操作需要10.01s才返回,而这与rpl_semi_sync_master_timeout参数的时间相吻合。

这时,查看两个状态的值,均为“OFF”了。

同时,主的error.log中打印如下信息:

2016-08-05T11:51:49.855452Z 6 [Warning] Timeout waiting for reply of binlog (file: mysql-bin.000003, pos: 1447), semi-sync up to file mysql-bin.000003, position 1196.
2016-08-05T11:51:49.855742Z 6 [Note] Semi-sync replication switched OFF.

3. 在Slave执行start slave后,主的insert操作很快就能返回,此时,两个状态的值也变为“ON”了。

同时,主的error.log中会打印如下信息:

2016-08-05T11:52:40.477098Z 7 [Note] Start binlog_dump to master_thread_id(7) slave_server(2), pos(mysql-bin.000003, 1196)
2016-08-05T11:52:40.477168Z 7 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 1196)
2016-08-05T11:52:40.523475Z 0 [Note] Semi-sync replication switched ON at (mysql-bin.000003, 1447)

其它变量

环境变量

mysql> show variables like '%Rpl%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+
7 rows in set (0.30 sec)

rpl_semi_sync_master_wait_for_slave_count

MySQL 5.7.3引入的,该变量设置主需要等待多少个slave应答,才能返回给客户端,默认为1。

rpl_semi_sync_master_wait_no_slave

ON

默认值,当状态变量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status依旧显示为ON。

OFF

当状态变量Rpl_semi_sync_master_clients中的值于rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status立即显示为OFF,即异步复制。

说得直白一点,如果我的架构是1主2从,2个从都采用了半同步复制,且设置的是rpl_semi_sync_master_wait_for_slave_count=2,如果其中一个挂掉了,对于rpl_semi_sync_master_wait_no_slave设置为ON的情况,此时显示的仍然是半同步复制,如果rpl_semi_sync_master_wait_no_slave设置为OFF,则会立刻变成异步复制。

状态变量

mysql> show status like '%Rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 6     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 1120  |
| Rpl_semi_sync_master_tx_wait_time          | 4483  |
| Rpl_semi_sync_master_tx_waits              | 4     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 4     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

上述状态变量中,比较重要的有以下几个

Rpl_semi_sync_master_clients

当前半同步复制从的个数,如果是一主多从的架构,并不包含异步复制从的个数。

Rpl_semi_sync_master_no_tx

The number of commits that were not acknowledged successfully by a slave.

具体到上面的测试中,指的是insert into test.test values(2)这个事务。

Rpl_semi_sync_master_yes_tx

The number of commits that were acknowledged successfully by a slave.

具体到上面的测试中,指的是以下四个事务

create database test;

create table test.test(id int);

insert into test.test values(1);

insert into test.test values(3);

六、总结

1. 在一主多从的架构中,如果要开启半同步复制,并不要求所有的从都是半同步复制。

2. MySQL 5.7极大的提升了半同步复制的性能。

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

5.7版本的半同步复制中,独立出一个 ack collector thread ,专门用于接收slave 的反馈信息。这样master 上有两个线程独立工作,可以同时发送binlog 到slave ,和接收slave的反馈。

参考

1. MariaDB原理与实现

2. http://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html

3. http://sanwen8.cn/p/105GRDe.html

4. 知数堂《MySQL 5.7 Replication新特性》分享

MySQL半同步复制(文章讲解很透彻!)相关推荐

  1. mysql 半同步复制_Mysql半同步复制原理及问题排查

    mysql半同步复制和异步复制的差别如上述架构图所示:在mysql异步复制的情况下,Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Master ...

  2. mysql 5.5半同步复制_(5.5)mysql高可用系列——MySQL半同步复制(实践)

    关键词,mysql半同步复制 [0]实验环境 操作系统:CentOS linux 7.5 数据库版本:5.7.24 数据库架构:主从复制,主库用于生产,从库用于数据容灾和主库备机,采用默认传统的异步复 ...

  3. MySQL · 源码分析 · MySQL 半同步复制数据一致性分析

    简介 MySQL Replication为MySQL用户提供了高可用性和可扩展性解决方案.本文介绍了MySQL Replication的主要发展历程,然后通过三个参数rpl_semi_sync_mas ...

  4. mysql半同步复制

    从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认的复制即是 ...

  5. mysql半同步复制实现

    mysql半同步复制和异步复制的区别如上述架构图所看到的:在mysql异步复制的情况下.Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Mast ...

  6. mysql半同步复制问题排查

    1.问题背景       默认情况下,线上的mysql复制都是异步复制,因此在极端情况下,主备切换时,会有一定的概率备库比主库数据少,因此切换后,我们会通过工具进行回滚回补,确保数据不丢失.半同步复制 ...

  7. MySQL 半同步复制+MMM架构

    介绍 上篇文章介绍了MMM架构的实现方法,但是上篇文章的MMM方案的复制是异步复制,异步复制的主要问题在于当主从存在延时时如果主机出现了故障导致了主从切换时这时将会存在数据丢失:mysql为了解决异步 ...

  8. MHA-结合MySQL半同步复制高可用集群(Centos7)

    目录 一.理论概述 本案例部署思路 二.环境 三.部署 部署MHA 部署二进制包MySQL及部署主从复制 部署半同步复制 配置MHA MHA测试 部署lvs+keepalived(lvs1,lvs2) ...

  9. 简述mysql半同步复制—semisync

    mysql的半同步复制-semisync是基于默认的异步复制和完全同步复制之间,它是在master在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个slave收到并写到relay log ...

最新文章

  1. MVC框架内容-模型
  2. mapReducer第一个例子WordCount
  3. SQL 中 left join、right join、inner join 的区别
  4. 设置eclipse中的编辑区的背景颜色、注释文字的颜色、修改注释内作者名和时间
  5. CMD命令之BAT脚本路径信息
  6. C/C++信息隐写术(二)之字符串藏入BMP文件
  7. 2017-2018-1 20155338 加分项目——PWD的实现
  8. iis php多版本共存,IIS7中多个版本php共存的方法
  9. 对象与控件如何建立关联
  10. android 进程间通信---bind的前世
  11. 用台式机搭建服务器测试环境_2020年十大最佳台式机环境
  12. google protobuf Linux环境下的安装与使用
  13. Python使用numpy模块实现矩阵和列表的连接操作
  14. Java架构学习(三十三)ActivityMQ基础消息中间件概述异步与同步MQ作用MQ件通讯方式MQ应用场景ActivityMQ安装使用ActivityMQ的案例主题和订阅
  15. cattee翻译_0302 echo、重定向、管道、cat、tee
  16. 如何用Python将Word文档转换为Excel表格
  17. Internal error: : 8 [#1] PREEMPT SMP ARM,vmlinux反汇编命令调试查找错误的步骤
  18. 为什么matlab的程序都加了分号,还会在命令行窗口不断输出
  19. 如何高效做好今日舆情信息监测与搜集的方法
  20. 计算机网络之应用层与传输层

热门文章

  1. WBEM简介 (转)
  2. 上海区块链会议演讲ppt_初级会议演讲者的建议
  3. 用户体验设计学习总结(上)
  4. 全局敏感度,局部敏感度和平滑敏感度到底有什么区别?【差分隐私】
  5. 最简单的SLIC算法实现
  6. 全球SPD市场迎来黄金时代,中国领跑全球增长
  7. 微型计算机显卡坞介绍,【宏碁 Veriton N 4640G 服务器外观展示】接口|显卡坞|光驱坞_摘要频道_什么值得买...
  8. 工具篇 之 Android WIFI ADB 实战
  9. wondershaper,一个CentOS系统控制网速的工具
  10. android tab切换菜单内容分页,8月23号   Tab菜单页面切换和jsp分页查询