首页 > 数据库 > MySQL > MySQL半同步复制
MySQL复制默认情况下是异步的,主库将事件写入binlog并不管从库是否接受并处理它们,如果主库崩溃时,已提交的事务可能没有被传送到从库,因此主从切换可能导致数据丢失。Semisynchronous Replication(半同步复制)则一定程度上保证提交的事务已经传给了至少一个备库。半同步
复制中,仅仅保证事务的已经传递到备库上,但是并不确保已经在备库上执行完成了。半同步复制确实有一定的性能影响,因为需要等待的从库确认。这是对增加数据的完整性的折衷。
工作原理:
当主库被阻塞时(已经提交的事务等待从从库确认),不会向执行事务的session返回信息;当主库阻塞结束后,返回session执行结果。
此时,主库事务已提交,至少一台从库确认接收到事务。
如果主备网络故障或者从库崩溃,主库在事务提交后等待10秒(rpl_semi_sync_master_timeout默认值)后,主从复制将自动降级为异步模式。
半同步复制是通过plugin实现的,master和slave使用不同的plugin。默认情况下没有安装该plugin,插件位于CMAKE_INSTALL_PREFIX/lib/plugin/。安装完插件之后,还需要手动设置系统参数以开启半同步复制模式。
[Master] 首先先检查 mysql是否支持动态添加插件 mysql> show variables like 'have_dynamic_loading'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | have_dynamic_loading | YES | +----------------------+-------+ 1 row in set (0.02 sec) mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; Query OK, 0 rows affected (0.04 sec) mysql> show variables like '%sem%'; +------------------------------------+-------+ | 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_no_slave | ON | +------------------------------------+-------+ 4 rows in set (0.00 sec) mysql> set global rpl_semi_sync_master_enabled = ON; Query OK, 0 rows affected (0.00 sec) mysql> set global rpl_semi_sync_master_timeout=2000; #毫秒 Query OK, 0 rows affected (0.00 sec) mysql> show status like '%sem%'; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 0 | # 有多少slave设置了半同步模式 | Rpl_semi_sync_master_net_avg_wait_time | 0 | # 事务提交后,等待备库响应的平均时间 | Rpl_semi_sync_master_net_wait_time | 0 | # 网络响应等待的总时间 | Rpl_semi_sync_master_net_waits | 0 | # 网络等待总次数 | Rpl_semi_sync_master_no_times | 0 | # 一共有几次从Semi-sync跌回普通状态 | Rpl_semi_sync_master_no_tx | 0 | # 备库未及时响应的事务次数 | Rpl_semi_sync_master_status | ON | # 主库上Semi-sync是否正常开启 | Rpl_semi_sync_master_timefunc_failures | 0 | # 时间函数未正常工作的次数 | Rpl_semi_sync_master_tx_avg_wait_time | 0 | # 开启Semi-sync,事务返回需要等待的平均时间 | 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 | # 备库成功响应的事务次数 +--------------------------------------------+-------+ 14 rows in set (0.01 sec) [Slave] mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.03 sec) mysql> show variables like '%sem%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_semi_sync_slave_enabled | OFF | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 2 rows in set (0.00 sec) mysql> set global rpl_semi_sync_slave_enabled = ON; Query OK, 0 rows affected (0.00 sec) 然后重启replication(stop slave;start slave;)即可。 一定需要重启,否则master无法确认该slave是否开启了半同步。相同的操作可以在任意多个slave中进行设置。 [slave] mysql> show status like '%sem%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Rpl_semi_sync_slave_status | ON | +----------------------------+-------+ 1 row in set (0.01 sec) [master] mysql> show status like '%sem%'; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | Rpl_semi_sync_master_net_avg_wait_time | 9978 | | Rpl_semi_sync_master_net_wait_time | 19957 | | Rpl_semi_sync_master_net_waits | 2 | | Rpl_semi_sync_master_no_times | 1 | | Rpl_semi_sync_master_no_tx | 2 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 0 | | 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 | +--------------------------------------------+-------+ 14 rows in set (0.00 sec)
状态说明:
Rpl_semi_sync_master_tx_avg_wait_time:事务因开启Semi_sync,平均需要额外等待的时间
Rpl_semi_sync_master_net_avg_wait_time:事务进入等待队列后,到网络平均等待时间
依据上面两个状态值可以知道,Semi-sync的网络消耗有多大,给某个事务带来的额外的消耗有多大。
Rpl_semi_sync_master_status: 表示主库当前Semi-sync是否正常工作
Rpl_semi_sync_slave_status: 表示从库当前Semi-sync是否正常工作
Rpl_semi_sync_master_no_times:可以知道一段时间内,Semi-sync是否有超时失败过,该计数器则记录了这样的失败次数。
Rplsemi_sync_master_wait_pos_backtraverse:在semisync_master中,维护了这样的两个变量wait_file_name和waitfile_pos,当主库上多个事务都在等待从库的响应时,这两个变量记录了所有等待中,最小的那一个Binlog位置。如果这时一个新的事务加入等待,并且该事务需要等待的Binlog比waitfile_name和waitfile_pos还小的话,则更新这两个值,并将Rpl_semi_sync_master_wait_pos_backtraverse值自增1。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29733787/viewspace-1246638/ ,如需转载,请注明出处,否则将追究法律责任。