安装MySQL半同步复制
一、简介
从MySQL5.5开始,MySQL以插件的形式支持半同步复制。如何理解半同步呢?首先我们来看看异步,全同步的概念
异步复制(Asynchronous replication)
MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,
这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致
新主上的数据不完整。
全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同
步复制的性能必然会收到严重的影响。
半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到
relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少
是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
下面来看看半同步复制的原理图:

半同步复制的潜在问题
客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种:
1.事务还没发送到从库上
此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份
重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。
2.事务已经发送到从库上
此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。
无数据丢失的半同步复制
针对上述潜在问题,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 #老的半同步方案,如图所示。
二、安装环境和要求
环境:

关闭防火墙
时间同步
连接网络并配置yum和epel源
安装要求:
. MySQL .5及以上版本(实验使用的为MySQL-5.6.36二进制版本)
. 变量have_dynamic_loading为YES
. 异步复制已经存在(主从)
三、安装与配置
1.在两台MySQL服务器上检查"have_dynamic_loading"是否为YES
mysql> show variables like 'have_dynamic_loading';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| have_dynamic_loading | YES |
+----------------------+-------+
2.master(192.168.1.11)服务器安装插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安装插件
Query OK, rows affected (0.20 sec) mysql> show plugins; #查看是否安装成功
+----------------------------+----------+--------------------+--------------------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+--------------------+---------+ |
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL |
+----------------------------+----------+--------------------+--------------------+---------+
rows in set (0.14 sec) mysql> SET GLOBAL rpl_semi_sync_master_enabled = ; #开启半同步复制,默认是关闭的
Query OK, rows affected (0.29 sec)
3.slave(192.168.1.12)服务器安装插件
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; #安装插件
Query OK, rows affected (0.29 sec) mysql> show plugins; #查看插件是否安装成功
+----------------------------+----------+--------------------+-------------------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+-------------------+---------+ |
| rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL |
+----------------------------+----------+--------------------+-------------------+---------+
rows in set (0.04 sec) mysql> SET GLOBAL rpl_semi_sync_slave_enabled = ; #开启半同步复制
Query OK, rows affected (0.02 sec) mysql> STOP SLAVE IO_THREAD; #重启从服务器IO线程,手动将异步模式切换为半同步模式
Query OK, rows affected (0.05 sec) mysql> START SLAVE IO_THREAD;
Query OK, rows affected (0.00 sec)
重启后,slave会在master上注册为半同步复制的slave角色。这时候,主的error.log中会打印如下信息:
-- :: [Note] Semi-sync replication initialized for transactions.
-- :: [Note] Semi-sync replication enabled on the master.
-- :: [Note] Stop asynchronous binlog_dump to slave (server_id: )
-- :: [Note] Start semi-sync binlog_dump to slave (server_id: ), pos(mysql-bin., )
4.查看半同步是否在运行
master(192.168.1.11):
mysql> show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON |
+-----------------------------+-------+
row in set (0.02 sec)
slave(192.168.1.12):
mysql> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
row in set (0.06 sec)
5.配置MySQL配置文件
master(192.168.1.11):
plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=
slave(192.168.1.12):
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=
在有的高可用架构下,master和slave需同时启动,以便在切换后能继续使用半同步复制(即同时安装master和slave插件)
plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
rpl-semi-sync-master-enabled =
rpl-semi-sync-slave-enabled =
6.查看相关参数
master(192.168.1.11):
mysql> show variables like '%semi%'; #环境变量
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | ON | #表示开启半同步复制
| rpl_semi_sync_master_timeout | | #默认1000毫秒,即10秒超时,将切换为异步复制
| rpl_semi_sync_master_trace_level | | #表示用于开启半同步复制时的调试级别,默认32
| rpl_semi_sync_master_wait_no_slave | ON | #表示是否允许master每个事物都要等待slave接收确认,默认为ON.说得直白一点,如果我的架构是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,则会立刻变成异步复制。
+------------------------------------+-------+
rows in set (0.00 sec)
mysql> show status like '%semi%'; #状态变量
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | | #表示从服务器有多少个配置成半同步复制
| Rpl_semi_sync_master_net_avg_wait_time | |
| Rpl_semi_sync_master_net_wait_time | |
| Rpl_semi_sync_master_net_waits | |
| Rpl_semi_sync_master_no_times | |
| Rpl_semi_sync_master_no_tx | | #表示从服务器确认失败提交的数量
| Rpl_semi_sync_master_status | ON | #表示主服务器使用是异步还是半同步复制
| Rpl_semi_sync_master_timefunc_failures | |
| Rpl_semi_sync_master_tx_avg_wait_time | |
| Rpl_semi_sync_master_tx_wait_time | |
| Rpl_semi_sync_master_tx_waits | |
| Rpl_semi_sync_master_wait_pos_backtraverse | |
| Rpl_semi_sync_master_wait_sessions | |
| Rpl_semi_sync_master_yes_tx | | #表示从服务器确认成功提交的数量
+--------------------------------------------+-------+
rows in set (0.00 sec)
slave(192.168.1.12):
mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON | #表示在slave已经开始半同步复制模式
| rpl_semi_sync_slave_trace_level | | #表示用于开启半同步复制时的调试级别,默认32
+---------------------------------+-------+
rows in set (0.20 sec)
mysql> show status like '%semi%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON | #表示从服务器开启半同步复制
+----------------------------+-------+
row in set (0.08 sec)
至此,MySQL半同步复制搭建完毕!
四、测试
事实上,半同步复制并不是严格意义上的半同步复制
当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。
下面来测试一下:
1.slave执行stop slave;关闭主从复制
mysql> stop slave;
Query OK, rows affected (0.32 sec)
2、master上创建一个表,没接收到反馈信号,等待十秒后(Rpl_semi_sync_master_timeout=1000等待超时),继续执行
mysql> use test;
Database changed
mysql> create table table1(id int);
Query OK, rows affected (10.48 sec) mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| table1 |
+----------------+
row in set (0.01 sec)
slave上查看是否有table1表
mysql> use test;
Database changed
mysql> show tables;
Empty set (0.00 sec)
3、master在数据库中再创建table2,不需要等待反馈,直接执行(因为当反馈超时时,master将切换到异步复制模式。此时是异步模式,不需要等待)
mysql> create table table2(id int);
Query OK, rows affected (0.11 sec) mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| table1 |
| table2 |
+----------------+
rows in set (0.00 sec)
4、slave执行start slave,数据开始同步,建立table1、table2,反馈给master,并切换为半同步复制
mysql> start slave;
Query OK, rows affected (0.07 sec) mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| table1 |
| table2 |
+----------------+
rows in set (0.01 sec)
总结:
. 在一主多从的架构中,如果要开启半同步复制,并不要求所有的从都是半同步复制。
. MySQL .7极大的提升了半同步复制的性能。
.6版本的半同步复制,dump thread 承担了两份不同且又十分频繁的任务:传送binlog 给slave ,还需要等待slave反馈信息,而且这两个任务是串行的,
dump thread 必须等待 slave 返回之后才会传送下一个 events 事务。dump thread 已然成为整个半同步提高性能的瓶颈。在高并发业务场景下,这样的机制
会影响数据库整体的TPS 。
.7版本的半同步复制中,独立出一个 ack collector thread ,专门用于接收slave 的反馈信息。这样 master 上有两个线程独立工作, 可以同时发送
binlog 到slave ,和接收slave的反馈。
参考:https://www.cnblogs.com/ivictor/p/5735580.html
安装MySQL半同步复制的更多相关文章
- MySQL半同步复制
		
从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认的复制即是 ...
 - Mysql半同步复制模式说明及配置示例 - 运维小结
		
MySQL主从复制包括异步模式.半同步模式.GTID模式以及多源复制模式,默认是异步模式 (如之前详细介绍的mysql主从复制).所谓异步模式指的是MySQL 主服务器上I/O thread 线程将二 ...
 - MySQL半同步复制(5.5之后引入)
		
半同步复制架构在主库提交一个事务后,commit完成即反馈客户端,无需等待推送binlog完成,如图: 半同步复制在主库完成一个事务后,需等待事务信息写入binlog日志并且至少有一个从库写入rela ...
 - mysql半同步复制实现
		
mysql半同步复制和异步复制的区别如上述架构图所看到的:在mysql异步复制的情况下.Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Mast ...
 - MySQL半同步复制搭建
		
默认情况下,MySQL 5.5/5.6/5.7和MariaDB 10.0/10.1的复制是异步的,异步复制可以提供最佳性能,主库把binlog日志发送给从库,这一动作就结束了,并不会验证从库是否接收完 ...
 - (5.5)mysql高可用系列——MySQL半同步复制(实践)
		
关键词,mysql半同步复制 [0]实验环境 操作系统:CentOS linux 7.5 数据库版本:5.7.24 数据库架构:主从复制,主库用于生产,从库用于数据容灾和主库备机,采用默认传统的异步复 ...
 - MySQL半同步复制的数据一致性探讨微信后台团队实践【转】
		
MySQL是一个RDBMS(关系型数据库管理系统),由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.由于其体积小.速度快.拥有成本低,尤其是开放源码这一特点,广受各大企业欢迎,包括 ...
 - mysql半同步复制跟无损半同步区别
		
mysql半同步复制跟无损半同步复制的区别: 无损复制其实就是对semi sync增加了rpl_semi_sync_master_wait_point参数,来控制半同步模式下主库在返回给会话事务成功之 ...
 - MySQL半同步复制源码解析
		
今天 DBA 同事问了一个问题,MySQL在半同步复制的场景下,当关闭从节点时使得从节点的数量 < rpl_semi_sync_master_wait_for_slave_count时,show ...
 
随机推荐
- 20165308 实验二 Java面向对象程序设计
			
20165308 实验二 Java面向对象程序设计 实验二 Java面向对象程序设计 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:张士洋 学号:20165308 指导教师:娄嘉鹏 ...
 - FireDAC探索 (二)
			
又花时间试了试FireDAC,本想找到一些办法,让FireDAC取数据能和DBX样快,最终还是失败了,DBX实现是太快了,3472第记录(110个字段的表),0毫秒就抓过来了, FireDAC最快也要 ...
 - Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)成功烧录方法
			
问题: Arduino:1.6.3 (Windows 7), 板:"Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)" Sketch ...
 - mysql日常处理
			
http://blog.csdn.net/zengxuewen2045/article/details/52349731 https://github.com/enmotplinux/On-Site- ...
 - IntelliJ IDEA maven项目 ***
			
创建一个新Maven项目 new 一个project 不选择任何Maven模板 起个GroupId.ArifactId 起个项目名.注意:Idea_Project是存放此项目的工作区间,mavenDe ...
 - ie8 报错:意外地调用了方法或属性访问
			
在某场景中一句简单的js: $("#changeOption").text("增加"); 在 IE8 下面报错:'意外地调用了方法或属性访问' 改成:$(&qu ...
 - 黄聪:ionic使用ion-nav-bar设置了bar-positive类但在安卓Android设备中无法置底
			
这时候还需要加这段代码: var app = angular.module("app", ["ionic" ]); app.config(["$ion ...
 - Intellij Idea编译项目下的.java文件时的编码问题
			
Intellij Idea编译项目下的.java文件时的编码问题 原创 2015年07月22日 21:45:14 10510 由<编译.java文件时的编码问题>可知,在编译.java文件 ...
 - Java判断两个List是否相同
			
1.利用Java中为List提供的方法retainAll() /** * 判断两个List内的元素是否相同 * <p> * 此方法有bug 见Food.class * * @param l ...
 - 经典面试题目——找到第n个丑数(参考《剑指offer(第二版)》面试题49)
			
一.题目大意 给你一个数n,要求返回第n个丑数.其中,丑数的定义如下: 丑数是指只包含因子2.3和5的数.(数字1也是丑数,不过是个特例)引用<剑指offer>上的话来说,对于一个数M,如 ...