MySQL复制(二)—— 半同步复制

记录备忘

参考博文:https://blog.csdn.net/wzy0623/article/details/90267132


目录

一、概述

二、原理

三、演进

3.1 线程的改进

3.1.1 旧版本

3.1.2 改进

3.2 二进制日志互斥锁改进

3.2.1 旧版本

3.2.2 改进

四、一致性分析

4.1 rpl_semi_sync_master_wait_point的配置

4.1.1 配置为WAIT_AFTER_COMMIT

4.1.2 配置为WAIT_AFTER_SYNC

4.2 sync_binlog的配置

4.3 sync_relay_log的配置

五、半同步相关配置

5.1 控制类参数

5.2 状态类参数

六、半同步实验

6.1 环境规划

6.2 配置异步复制

6.3 配置半同步复制

6.3.1 安装插件

6.3.2 启用半同步复制

七、测试

7.1 正常提交事务

7.2 回滚事务

7.3 主库等待超时

7.3.1 rpl_semi_sync_master_wait_no_slave为ON

7.3.2 rpl_semi_sync_master_wait_no_slave为OFF


一、概述

主从复制主要分三种类型:异步、半同步、同步。

  • 异步复制:主库提交事务时,将事件写入它的二进制日志,而从库在准备就绪时请求它们。主库无需等待从库的ACK回复,直接提交事务并返回客户端。异步复制不确保所有事件都能到达从库,无法保证数据完整性。
  • 半同步复制:介于异步和完全同步复制之间。主库仅等待至少一个从库接收并记录事件。它不会等待所有从库确认收到,并且从库只需要确认接收,而不是事件已在从库完全执行和提交。当主库等待回复超时后自动转为异步。
  • 同步复制:当主库提交事务时,所有从库也将在主库返回执行事务的会话之前提交事务。这样做的缺点是完成事务可能会有很大延迟。

与异步复制相比,半同步复制提供了改进的数据完整性,因为当提交成功返回时,已知数据至少存在于两个位置。但半同步复制确实会对性能产生一些影响,因为需要等待从库,提交速度会变慢,延迟至少是将提交发送到从库并等待从库确认收到的TCP/IP往返时间。这意味着半同步复制最好在低延时的网络中使用。

 

二、原理

半同步复制时,为了保证主库上的每一个Binlog事务都能够被可靠的复制到从库上,主库在每次事务成功提交时,并不及时反馈给前端应用用户,而是等待其中的一个从库也接收到Binlog事务并成功写入中继日志后,主库才返回commit操作成功给客户端。半同步复制保证了事务成功提交后,至少有两份日志记录,一份在主库的Binlog日志上,另一份在至少一个从库的中继日志Relay log上,从而更近一步保证了数据的完整性。

三、演进

3.1 线程的改进

3.1.1 旧版本

旧版本的半同步复制受限于Binlog Dump线程,原因是该线程承担了两份不同且又十分频繁的任务:

  • 传送二进制日志事件给从库
  • 接收从库的ACK反馈信息

这两个任务是串行的,Binlog Dump线程必须等待从库返回之后才会传送下一个事件。Binlog Dump线程已然成为整个半同步复制性能的瓶颈。在高并发业务场景下,这样的机制会影响数据库整体的TPS。单一Binlog Dump线程发送接收的工作流程如图1所示。

MySQL复制(二)—— 半同步复制_第1张图片 图1 单一Binlog Dump线程发送接收的工作流程图

3.1.2 改进

在5.7.4版本的半同步复制框架中,独立出一个Ack Receiver线程 ,专门用于接收从库返回的ACK请求,这将之前Binlog Dump线程的发送和接收工作分为了两个线程来处理。这样主库上有两个线程独立工作,可以同时发送二进制日志事件到从库,和接收从库的ACK信息。因此半同步复制得到了极大的性能提升。Binlog Dump线程与Ack Receiver线程工作流程如图2所示。

MySQL复制(二)—— 半同步复制_第2张图片 图2 Binlog Dump线程与Ack Receiver线程工作流程图

Ack Receiver线程在主库启用半同步复制时创建,并在主库禁用半同步复制时销毁。它是自动创建和销毁的,因此不受用户控制。它的状态信息可以在performance_schema中查询得到:

select name, type, processlist_state from performance_schema.threads where name like '%ack_receiver%';
+------------------------------+------------+--------------------------------------+
| name                         | type       | processlist_state                    |
+------------------------------+------------+--------------------------------------+
| thread/semisync/Ack_receiver | BACKGROUND | Waiting for semi-sync ACK from slave |
+------------------------------+------------+--------------------------------------+

Ack receiver线程有以下三个状态:

  • Waiting for semi-sync slave connection
  • Waiting for semi-sync ACK from slave
  • Reading semi-sync ACK from slave

在MySQL 5.7.17之前,这个Ack Receiver线程采用了select机制来监听从库返回的结果,然而select机制监控的文件句柄只能是0-1024,当超过1024时,用户在MySQL的错误日志中或许会收到类似如下的报错,更有甚者会导致MySQL发生宕机。

semi-sync master failed on net_flush() before waiting for slave reply.

        MySQL 5.7.17版本开始,官方修复了这个bug,开始使用poll机制来替换原来的select机制,从而可以避免上面的问题。其实poll调用本质上和select没有区别,只是在I/O句柄数理论上没有上限了,原因是它是基于链表来存储的。

3.2 二进制日志互斥锁改进

3.2.1 旧版本

旧版本半同步复制在主库提交二进制日志的写会话和Binlog Dump线程读取二进制日志的操作都会对二进制日志添加binlog lock互斥锁,用于保护二进制日志的读写操作。使用此互斥锁,二进制日志读写操作是安全的,但会导致二进制日志文件的读写串行化。不仅Binlog Dump线程和用户会话不能同时读写二进制日志,就连多个Binlog Dump线程本身也无法同时读取。每当一个会话正在读取或写入二进制日志文件时,所有其它会话都必须等待。如此顺序读写可能是一个瓶颈,尤其是当读写操作很慢时。串行化读写二进制日志如图3所示。

MySQL复制(二)—— 半同步复制_第3张图片 图3 串行化读写二进制日志示意图

3.2.2 改进

MySQL 5.7.2对binlog lock进行了以下两方面优化:

  • 从Binlog Dump线程中移除binlog lock。
  • 加入了安全边际保证二进制日志的读安全。

二进制日志文件看起来像一个仅追加的日志文件,可以安全地读取没有锁定的二进制事件。因此从Binlog Dump线程中删除了binlog锁。不使用binlog锁,而是为活动binlog维护安全读取边界(最大位置)。Binlog Dump线程永远不会读取超过安全读取边界的位置。当边界到达边界时,它将等待边界更新。用户会话负责在追加了二进制事件后更新安全读取边界。改进后的二进制日志读写如图4所示。

MySQL复制(二)—— 半同步复制_第4张图片 图4 改进后的二进制日志读写示意图

从图中可知:

  • 读取二进制日志事件时,Binlog Dump线程不会相互阻塞。
  • 正在写二进制日志事件的用户会话不会阻止Binlog Dump线程。
  • 读取二进制日志事件的Binlog Dump不会阻塞用户会话。

        因此,Binlog Dump线程和用户会话都可以获得更好的吞吐量,尤其是当有很多从库时,这种改进非常显着。

四、一致性分析

主库在等待备库ack时候,如果超时会退化为异步,这就可能导致数据丢失。在接下来分析中,先假设rpl_semi_sync_master_timeout足够大,不会退化为异步方式。

这里通过以下三个参数分析:

  • rpl_semi_sync_master_wait_point
  • sync_binlog
  • sync_relay_log

4.1 rpl_semi_sync_master_wait_point的配置

4.1.1 配置为WAIT_AFTER_COMMIT

rpl_semi_sync_master_wait_point为WAIT_AFTER_COMMIT时,commitTrx的调用在engine层commit之后,如图5所示。

MySQL复制(二)—— 半同步复制_第5张图片 图5 WAIT_AFTER_COMMIT同步流程图

主库在等待Slave ACK时候,虽然没有返回当前客户端,但事务已经提交,其他客户端会读取到已提交事务。如果Slave端还没有读到该事务的events,同时主库发生了crash,然后切换到备库。那么之前读到的事务就不见了,出现了幻读。另外,如果客户端会重试提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中。此时会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的,结果依然是主从数据不一致。

4.1.2 配置为WAIT_AFTER_SYNC

MySQL针对上述问题,在5.7.2中改为调用binlog sync之后,engine层commit之前等待Slave ACK。这样只有在确认Slave收到事务events后,事务才会提交。在commit之前等待Slave ACK,同时可以堆积事务,利于group commit,有利于提升性能。如图6所示。

MySQL复制(二)—— 半同步复制_第6张图片 图6 WAIT_AFTER_SYNC同步流程图

4.2 sync_binlog的配置

当sync_binlog为0的时候,binlog sync磁盘由操作系统负责。当不为0的时候,其数值为定期sync磁盘的binlog commit group数。当sync_binlog值大于1的时候,sync binlog操作可能并没有使binlog落盘。如果没有落盘,事务在提交前,Master掉电,然后恢复,那么这个时候该事务被回滚。但是Slave上可能已经收到了该事务的events并且执行,这个时候就会出现Slave事务比Master多的情况,主备同步会失败。所以如果要保持主备一致,需要设置sync_binlog为1。

WAIT_AFTER_SYNC和WAIT_AFTER_COMMIT两图中Send Events的位置,也可能导致主备数据不一致,出现同步失败的情形。实际在rpl_semi_sync_master_wait_point分析的图中是sync binlog大于1的情况。根据上面源码,流程如图7所示。Master依次执行flush binlog,update binlog position,sync binlog。如果Master在update binlog position后,sync binlog前掉电,Master再次启动后原事务就会被回滚。但可能出现Slave获取到Events,这也会导致Slave数据比Master多,主备同步失败。

MySQL复制(二)—— 半同步复制_第7张图片 图7 binlog大于1的落盘流程图

由于上面的原因,sync_binlog设置为1的时候,MySQL会update binlog end pos after sync。流程如图8所示。这时候,对于每一个事务都需要sync binlog,同时sync binlog和网络发送events会是一个串行的过程,性能下降明显。

MySQL复制(二)—— 半同步复制_第8张图片 图8 sync_binlog等于1的落盘流程图

4.3 sync_relay_log的配置

当sync_relay_log不是1的时候,semisync返回给Master的position可能没有sync到磁盘。在gtid_mode下,在保证前面两个配置正确的情况下,sync_relay_log不是1的时候,仅发生Master或Slave的一次Crash并不会发生数据丢失或者主备同步失败情况。如果发生Slave没有sync relay log,Master端事务提交,客户端观察到事务提交,然后Slave端Crash。这样Slave端就会丢失掉已经回复Master ACK的事务events。

MySQL复制(二)—— 半同步复制_第9张图片 图9 relaylog落盘流程图

  但当Slave再次启动,如果没有来得及从Master端同步丢失的事务Events,Master就Crash。这个时候,用户访问Slave就会发现数据丢失。

MySQL复制(二)—— 半同步复制_第10张图片 图10 数据丢失示意图

 

五、半同步相关配置

半同步配置是通过插件方式完成的。

  • 主库端的:semisync_master.so
  • 从库端的:semisync_slave.so

5.1 控制类参数

  • rpl_semi_sync_master_enabled:主库上启用半同步复制。此变量分别设置为1或0,默认值为0(关闭)
  • rpl_semi_sync_slave_enabled:从库上启用半同步复制。此变量分别设置为1或0,默认值为0(关闭)
  • rpl_semi_sync_master_timeout:等待从库确认提交的时间,等待超过该值退化为异步。默认值为10000(10秒)

5.2 状态类参数

  • Rpl_semi_sync_master_clients:当前连接了多少个半同步从库。
  • Rpl_semi_sync_master_net_avg_wait_time:主库等待从库回复的平均时间,以微秒为单位。此变量始终为0,不推荐使用,并且将在以后的版本中删除。
  • Rpl_semi_sync_master_net_wait_time:主库等待从库回复的总时间,以微秒为单位。此变量始终为0,不推荐使用,并且将在以后的版本中删除。
  • Rpl_semi_sync_master_net_waits:主库等待从库回复的总次数。
  • Rpl_semi_sync_master_no_times:主库关闭半同步复制的次数。
  • Rpl_semi_sync_master_no_tx:从库未成功确认的事务数。
  • Rpl_semi_sync_master_status:为ON时表示主库使用半同步复制,OFF表示主库使用异步复制。
  • Rpl_semi_sync_master_timefunc_failures:调用gettimeofday等时间函数时主库失败的次数。
  • 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:从库成功确认的事务数。

仅当使用INSTALL PLUGIN安装了相应的插件时,系统和状态变量才可用。

 

六、半同步实验

6.1 环境规划

  • 虚拟服务器
IP 角色
192.168.56.11
192.168.56.12
192.168.56.13
  • 软件
软件名称

软件版本

OS CentOS Linux release 7.3.1611 (Core)
MySQL mysql-8.0.21
  • 路径
路径 用途
/home/mysql/mysql8 MySQL主目录
/home/mysql/mysql8/data MySQL数据目录
/home/mysql/mysql8/logs/binlog MySQL二进制日志目录
/home/mysql/mysql8/logs/relaylog MySQL中继日志目录

6.2 配置异步复制

见 “MySQL复制(一)—— 异步复制” 的配置过程

6.3 配置半同步复制

6.3.1 安装插件

半同步复制是使用插件实现的,因此必须将插件安装到MySQL服务器中才能使用它们。安装插件后,可以通过与之关联的系统变量来控制它。安装插件之前,这些系统变量是不可用的。要使用半同步复制,必须满足以下要求:

  • 安装插件需要MySQL服务器支持动态加载。要验证这一点,检查have_dynamic_loading系统变量的值是否为YES。MySQL 8缺省为YES。
  • 已经启动了异步复制。
  • 半同步不支持多源复制。      
  • 安装设置半同步复制,需要REPLICATION_SLAVE_ADMIN或SUPER权限。

MySQL发行版包括主、从端的半同步复制插件文件semisync_master.so和semisync_slave.so,缺省位于MySQL安装目录下的lib/plugin目录下,本例中为/usr/local/mysql/lib/plugin。也可以通过设置plugin_dir系统变量的值指定插件目录位置。执行下面的SQL语句加载插件。

-- 在主库
install plugin rpl_semi_sync_master soname 'semisync_master.so';
 
-- 在每个从库
install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

建议在主从库都安装以上插件。这样便于主从切换

如果尝试安装插件导致Linux上出现类似于此处所示的错误,则必须安装libimf:

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
ERROR 1126 (HY000): Can't open shared library
'/usr/local/mysql/lib/plugin/semisync_master.so'
(errno: 22 libimf.so: cannot open shared object file:No such file or directory)

可以从https://dev.mysql.com/downloads/os-linux.html获取libimf。

检查INFORMATION_SCHEMA.PLUGINS表或使用SHOW PLUGINS语句验证插件安装,例如:

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> show variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| 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 |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

--从库
mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | OFF   |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)

6.3.2 启用半同步复制

安装半同步复制插件后,默认情况下会禁用它。必须在主库和从库都启用插件才能启用半同步复制。如果仅启用一侧,则复制将是异步的

-- 主库
set global rpl_semi_sync_master_enabled = 1;
 
-- 从库
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

 重启从库上的I/O线程,重启后,从库会在主库上注册为半同步复制的从库角色。

-- 从库执行
mysql> stop slave io_thread;
mysql> start slave io_thread;

查看半同步是否在运行 

-- 主库
mysql> show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.01 sec)
 
-- 从库
mysql> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

 这两个变量常用来监控主从是否运行在半同步复制模式下。至此,MySQL半同步复制搭建完毕。

 

七、测试

7.1 正常提交事务

-- 主
mysql> create database db_test;
Query OK, 1 row affected (0.00 sec)
 
mysql> use db_test;
Database changed
mysql> create table db_test.t1 (a int) engine=innodb;
Query OK, 0 rows affected (0.02 sec)
 
mysql> insert into t1 values(1);
Query OK, 1 row affected (0.02 sec)
 
mysql> show status like 'rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 2     |
| 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              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 758   |
| Rpl_semi_sync_master_tx_wait_time          | 2274  |
| Rpl_semi_sync_master_tx_waits              | 3     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 3     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
mysql>
-- 从
mysql> select * from test.t1;
+------+
| a    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

MySQL 8缺省是每条语句自动提交的。主库等待3个事务的确认,分别对应create database、create table、insert语句。平均每个事务等待758微妙,从库正常确认了3个事务。

7.2 回滚事务

-- 开启事物
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

-- 向事务表插入记录
mysql> insert into t1 values(2);                  
Query OK, 1 row affected (0.00 sec)

-- 执行一个DDL语句,创建非事务表t2
mysql> create table t2 (a int) engine=myisam;     
Query OK, 0 rows affected (0.01 sec)

-- 向事务表插入记录
mysql> insert into t1 values(3);                  
Query OK, 1 row affected (0.00 sec)

-- 向非事务表插入记录
mysql> insert into t2 values(3);                  
Query OK, 1 row affected (0.01 sec)

-- 回滚事务
mysql> rollback;                                 
Query OK, 0 rows affected, 1 warning (0.00 sec)

-- 查看警告
mysql> show warnings;
+---------+------+---------------------------------------------------------------+
| Level   | Code | Message                                                       |
+---------+------+---------------------------------------------------------------+
| Warning | 1196 | Some non-transactional changed tables couldn't be rolled back |
+---------+------+---------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from t1;
+------+
| a    |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)
 
mysql> select * from t2;
+------+
| a    |
+------+
|    3 |
+------+
1 row in set (0.00 sec)
 
mysql> show status like 'rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 2     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 12    |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 691   |
| Rpl_semi_sync_master_tx_wait_time          | 4149  |
| Rpl_semi_sync_master_tx_waits              | 6     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 6     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

从上面的测试可以得出以下结论:

  • set session autocommit=0语句不被复制。
  • DDL语句会触发一个commit,自动提交DDL语句本身及其前面未提交的事务。
  • 非事务表不能回滚。
  • Rpl_semi_sync_master_tx_waits和Rpl_semi_sync_master_yes_tx都增加了3,分别对应
    • insert into t1 values(2);
    • create table t2 (a int) engine=myisam;
    • insert into t2 values(3);三个事务。

7.3 主库等待超时

7.3.1 rpl_semi_sync_master_wait_no_slave为ON

从库数小于rpl_semi_sync_master_wait_for_slave_count值(收到多少个从库的回复认为事务完成,主库返回客户端commit,默认值1),需要等待rpl_semi_sync_master_timeout的时间后才会退化为异步。

-- 2从库都关闭IO线程
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)

-- 主库插入事物数据
mysql> insert into t1 values (4);
Query OK, 1 row affected (10.01 sec) -- 等待从库10秒

-- 主库转为异步
mysql> show status like '%Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | OFF   |
+-----------------------------+-------+

7.3.2 rpl_semi_sync_master_wait_no_slave为OFF

从库数小于rpl_semi_sync_master_wait_for_slave_count值(收到多少个从库的回复认为事务完成,主库返回客户端commit,默认值1),无需等待rpl_semi_sync_master_timeout,直接退化为异步。

-- 主库关闭rpl_semi_sync_master_wait_no_slave
mysql> set global rpl_semi_sync_master_wait_no_slave=off;
Query OK, 0 rows affected (0.00 sec)

-- 2从库都关闭IO线程
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)

-- 主库插入事物数据
mysql> insert into t1 values (5);
Query OK, 1 row affected (0.01 sec) -- 无等待,立刻提交

-- 主库转为异步
mysql> show status like '%Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | OFF   |
+-----------------------------+-------+


全文完。

你可能感兴趣的:(MySQL,mysql)