本文作为新书《深入理解MySQL主从原理》的补充部分,供大家参考,如有误请见谅。
数据结构和流程参考:
此处不再单独列出
查看大图请移步 https://www.jianshu.com/p/5ebf4f4c1cf8
半同步插件是否注册:半同步插件注册状态
ReplSemiSyncMaster::init_done_
/* True when initObject has been called */
半同步插件是否启用:半同步开启状态
ReplSemiSyncMaster::master_enabled_
/* semi-sync is enabled on the master */
getMasterEnabled用于获取变量
set_master_enabled设置变量
完全取决于参数rpl_semi_sync_master_enabled
是否使用半同步(异步):半同步复制方式
ReplSemiSyncMaster::state_
/* whether semi-sync is switched */
本状态非常重要,决定了是否是半同步复制方式,在函数ReplSemiSyncMaster::commitTrx中会完全依赖这个状态决定是否进行用户线程事务的等待,也是Rpl_semi_sync_master_status信息的来源。
研究的参数包括
| 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 |
默认为false
生效点:
fix_rpl_semi_sync_master_enabled函数会动态转换为半同步开启状态,并且开启Ack_receiver线程,当然根据参数rpl_semi_sync_master_wait_for_slave_countrpl_semi_sync_master_wait_no_slave 的设置,考虑是否使用同步复制方式,并且本参数会设置到 ReplSemiSyncMaster::master_enabled_ 全局变量。如果是关闭则会转化为异步复制switch_off(),并且做一些清理操作,比如active_tranxs_。
默认为10000毫秒,即10秒
生效点:
默认为on 本参数可以和参数rpl_semi_sync_master_wait_no_slave共同作用共同决定半同步复制还是异步复制,这里先说rpl_semi_sync_master_wait_no_slave设置on的情况 生效点:
因此和rpl_semi_sync_master_timeout参数配合,可以决定收到多少个半同步从库的ack后进行反馈。
默认为on
如果为on则遵守如上rpl_semi_sync_master_wait_for_slave_count的说明,这里重点说一下它设置为false有什么作用,如果其设置为false那么会有如下影响
生效点:
因此本参数设置为false,设置rpl_semi_sync_master_timeout为一个很大的值,也不能保证主从一定是半同步复制。
默认为32
我们在前面已经多次说过,如果这个参数设置16,将会有大量的半同步日志输出。这里不做描述
默认为AFTER_SYNC,这个参数也是在前面说过了,这里不做详细描述。
生效点:
主要研究的统计值包含
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | OFF |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
内部为rpl_semi_sync_master_off_times
内部为rpl_semi_sync_master_no_transactions。
内部为rpl_semi_sync_master_yes_transactions。
参考ReplSemiSyncMaster::setExportStats函数
内部表示为rpl_semi_sync_master_trx_wait_time。
从库的参数和统计值很简单,和主库不同开启rpl_semi_sync_slave_enabled参数,不会动态让从库的Rpl_semi_sync_slave_status生效,启用半同步复制方式
生效点为
无法动态开启这点和主库不同,并且此状态不会由于主库问题在运行期间改变,因此不能做判断半同步复制方式的根据,应该在主库判断。 改变:
下面是一个测试(主库未安装半同步插件)
mysql> show variables like '%semi%slave_enabled';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
+-----------------------------+-------+
1 row in set (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.02 sec)
mysql> show status like '%Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF |
+----------------------------+-------+
可以看到Rpl_semi_sync_slave_status并未启动。
下面是另外一个测试
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Reconnecting after a failed master event read
Master_Host: 192.168.1.63
Master_User: repsem
Master_Port: 3325
Connect_Retry: 60
Master_Log_File: log_bin.000004
Read_Master_Log_Pos: 194
Relay_Log_File: relaylog.000020
Relay_Log_Pos: 363
Relay_Master_Log_File: log_bin.000004
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
ERROR:
No query specified
mysql> show status like '%Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.02 sec)
可以看到即便IO线程已经处于重连状态,Rpl_semi_sync_slave_status依旧为on。
ReplSemiSyncMaster::commitTrx
->switch_off
repl_semi_binlog_dump_end
->ReplSemiSyncMaster::remove_slave
->switch_off
ReplSemiSyncMaster::reportReplyPacket
->handleAck
->ReplSemiSyncMaster::reportReplyBinlog
->try_switch_on
全文完。
Enjoy MySQL :)