半同步复制:

我们知道在默认情况下,MySQL的复制是异步的,这意味着主服务器及其从服务器是独立的。

MySQL主从同步的异步复制可以提供最佳的性能,因为主服务器在将更新的数据写入它的二进制日志(Binlog)文件中后,无需等待验证更新数据是否已经复制到从服务器中,就可以自由处理其它进入的事务处理请求。但这也同时带来了很高的风险,如果在主服务器或从服务器端发生故障,会造成主从数据的不一致,甚至在恢复时造成数据丢失。

异步复制原理图,如下:

半同步复制是从MySQL5.5开始引入了一种半同步复制功能,该功能可以确保主服务器和访问链中至少一台从服务器之间的数据一致性和冗余。在这种配置结构中,一台主服务器和其许多从服务器都进行了配置,这样在复制拓扑中,至少有一台从服务器在父主服务器进行事务处理前,必须确认更新已经收到并写入了其中继日志(Relay Log)。当出现超时,源主服务器必须暂时切换到异步复制模式重新复制,直到至少有一台设置为半同步复制模式的从服务器及时收到信息。

半同步复制原理图,如下:

1、异步复制(Asynchronous replication)  

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

2、全同步复制(Fully synchronous replication)

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端

因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

3、半同步复制(Semisynchronous replication)

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

 

下面我们看一下怎么从普通复制转化为半同步复制。

假设我们已经搭建完成一主两从的GTID复制环境:

MySQL1:172.16.16.35:3306

MySQL2:172.16.16.35:3307

MySQL3:172.16.16.34:3306

这个环境因为我之前测试MHA的时候已经是搭建好了,就不在强调怎么去搭建一个普通的GTID复制环境了,下面我们看一下怎么安装

(1)安装插件,三台MySQL服务器都要执行:

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

我们可以通过以下语句查看是否安装成功:

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE |
| rpl_semi_sync_slave | ACTIVE |
+----------------------+---------------+
2 rows in set (0.00 sec)

 

在三台MySQL的配置文件当中添加如下的参数:

rpl_semi_sync_master_enabled=1     # 开启半同步复制
rpl_semi_sync_slave_enabled=on;    # 打开半同步复制

 

然后重启数据库,不安装semisync_master.so的话是不能识别这个参数的,所以说这个参数要等安装完以后在重启。

(2)重启完成后,默认就是半同步复制了,开始看一下半同步相关的参数

mysql> show variables like 'rpl_se%';
+-------------------------------------------+------------+
| 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_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+-------------------------------------------+------------+
8 rows in set (0.00 sec)

 

上面参数具体含义:

rpl_semi_sync_master_enabled :主库是否打开半同步复制

rpl_semi_sync_master_timeout :毫秒为单位,当主库等待从库ACK的实践超过这个值,就会自动转化为异步复制

rpl_semi_sync_master_trace_level :master的trace 级别,分为四个(1,16,32,64),分别记录不同的信息,32能够输出更详细的网络延迟等信息,也是默认值

rpl_semi_sync_master_wait_for_slave_count :至少有N个slave接收到日志,一主多从的情况下只要有一个slave的ACK返回给了主库,就会进行commit

rpl_semi_sync_master_wait_no_slave:默认为ON,当半同步复制转换为异步复制后,如果从库的日志追赶上了主库,会自动转换为半同步复制,设置为OFF的话就不会再进行转换。

rpl_semi_sync_slave_enabled :从库是否打开半同步复制功能

rpl_semi_sync_slave_trace_level :trace 级别

rpl_semi_sync_master_wait_point :这是MySQL5.7新增的功能,可以设置两个值AFTER_SYNC 和AFTER_COMMIT,AFTER_COMMIT的模式下master将每个事务写入binlog ,传递到slave 刷新到磁盘(relay log),同时主库提交事务。master等待slave 反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。AFTER_SYNC 情况下master 将每个事务写入binlog , 传递到slave 刷新到磁盘(relay log)。master等待slave 反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。 即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。我们推荐使用默认AFTER_SYNC 的情况,这样可以提高性能,减少等待时间。

 

此外在MySQL5.7的半同步复制当中还移除了dump thread对binlog的互斥锁, 解决了在高并发环境下串行读取binlog的问题。

 

 

参考推荐:

MySQL 5.5 异步、半同步、全同步复制

Java JDK升级各个版本的新特性

MySQL 主流版本更新记录

MySQL 事务隔离级别和实现原理

数据库分库分表的解决方案比较

分布式系统事务一致性解决方案

MySQL 数据库主从心得整理

MySQL命令操作(Linux平台)

MySQL 删除数据后物理空间未释放

MySQL 查看数据库大小、表大小和最后修改时间  (推荐

PHP MySQL中 uft-8中文编码乱码的解决办法

MySQL 常用语法总结

MySQL 时间函数加减计算  (推荐

MySQL 创建索引、修改索引、删除索引的命令

MySQL 存储引擎InnoDB和MyISAM区别

MySQL 执行sql及慢查询监控

MySQL 中case when语句用法

MySQL 函数 group_concat

MySQL 中 distinct 和 group by 性能比较

MySQL 查询语句取整数或小数

统计Redis中各种数据的大小

主键与唯一索引的区别

Java 程序员必读的经典书籍

网站更新日志的几种样式与实现