半同步复制:
什么是半同步复制?我们知道在默认情况下,MySQL的复制是异步的,这意味着主服务器及其从服务器是独立的。异步复制可以提供***的性能,因为主服务器在将更新的数据写入它的二进制日志(Binlog)文件中后,无需等待验证更新数据是否已经复制到从服务器中,就可以自由处理其它进入的事务处理请求。但这也同时带来了很高的风险,如果在主服务器或从服务器端发生故障,会造成主从数据的不一致,甚至在恢复时造成数据丢失。
半同步复制是从MySQL5.5开始引入了一种半同步复制功能,该功能可以确保主服务器和访问链中至少一台从服务器之间的数据一致性和冗余。在这种配置结构中,一台主服务器和其许多从服务器都进行了配置,这样在复制拓扑中,至少有一台从服务器在父主服务器进行事务处理前,必须确认更新已经收到并写入了其中继日志(Relay Log)。当出现超时,源主服务器必须暂时切换到异步复制模式重新复制,直到至少有一台设置为半同步复制模式的从服务器及时收到信息。
下面我们看一下怎么从普通复制转化为半同步复制。假设我们已经搭建完成一主两从的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的问题。