前言:
对于MySQL的主从复制来说,是一个异步同步的过程。这样,在同步过程中,就可能出现主库异常宕机,且无法修复,从库数据丢失的情况。
半同步方式是google为mysql开发的一个补丁,在MySQL 5.5或者更高的版本中已经集成了这个功能。半同步的意思表示MASTER 只需要接收到其中一台SLAVE的返回信息,就会commit;否则需等待直至达到超时时间然后切换成异步再提交。这么做可以使主从库的数据的延迟较小,可以在损失很小的性能的前提下提高数据的安全性。一句话说:半同步就是为了最大限度的保持数据的一致性和安全性,建立在主从架构基础上,而非主主架构!
实施步骤:
- - 实验环境说明
master 192.168.0.102
slave 192.168.0.103
- - master 与slave已经是主从关系.数据库版本为5.5.36
在master和slave 查询数据库是否支持动态添加插件(其实我的版本已经默认支持且安装了)
mysql> select @@have_dynamic_loading ; +------------------------+ | @@have_dynamic_loading | +------------------------+ | YES | +------------------------+ 1 row in set (0.00 sec) #YES表示支持。 从库查询此处略过.
2. 在master和slave分别查看目前mysql状态有没有启用半同步
mysql> show variables like 'rpl%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | rpl_recovery_rank | 0 | +-------------------+-------+ 1 row in set (0.00 sec) # Value为0表示目前 未启用. #从库操作也是这样,此处略过.
3. 在master和slave上,分别安装半同步插件
# master端 mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; Query OK, 0 rows affected (0.05 sec) # slave端 mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.03 sec)
4. 在master端启用半同步
#未启动前状态查看 mysql> show variables like 'rpl%'; +------------------------------------+-------+ | Variable_name | Value | +------------------------------------+-------+ | rpl_recovery_rank | 0 | | 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 | +------------------------------------+-------+ 5 rows in set (0.00 sec) # 启动, 并查看启动结果 mysql> set global rpl_semi_sync_master_enabled=1; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'rpl%'; +------------------------------------+-------+ | Variable_name | Value | +------------------------------------+-------+ | rpl_recovery_rank | 0 | | rpl_semi_sync_master_enabled | ON | | rpl_semi_sync_master_timeout | 10000 | | rpl_semi_sync_master_trace_level | 32 | | rpl_semi_sync_master_wait_no_slave | ON | +------------------------------------+-------+ 5 rows in set (0.00 sec) # rpl_semi_sync_master_timeout 默认为10000,单位是毫秒,可以根据实际环境修改 # 修改命令为:set global rpl_semi_sync_master_timeout=1000; # 发现 rpl_semi_sync_master_enabled --> Value: ON,表示启用“主”角色的半同步插件
5. 在slave端启用半同步
# 未启动前状态 mysql> show variables like 'rpl%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_recovery_rank | 0 | | rpl_semi_sync_slave_enabled | OFF | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 3 rows in set (0.00 sec) # 启动,并查看执行结果 mysql> set global rpl_semi_sync_slave_enabled=1; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'rpl%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_recovery_rank | 0 | | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 3 rows in set (0.00 sec) # 发现 rpl_semi_sync_slave_enabled --> Value: ON,表示启用“从”角色的半同步插件.但是此时 # 仅仅是启用,并未在当前运行状态激活. 所以还需要执行下面的步骤. # 步骤1: # 此时查看运行状态 mysql> show status like 'rpl%'; +----------------------------+-------------+ | Variable_name | Value | +----------------------------+-------------+ | Rpl_semi_sync_slave_status | OFF | | Rpl_status | AUTH_MASTER | +----------------------------+-------------+ #发现为OFF状态. 2 rows in set (0.00 sec) # 步骤2:激活半同步--> 也就是restart io线程 mysql> stop slave io_thread; Query OK, 0 rows affected (0.00 sec) mysql> start slave io_thread; Query OK, 0 rows affected (0.00 sec) mysql> show status like 'rpl%'; +----------------------------+-------------+ | Variable_name | Value | +----------------------------+-------------+ | Rpl_semi_sync_slave_status | ON | | Rpl_status | AUTH_MASTER | +----------------------------+-------------+ 2 rows in set (0.00 sec) # 发现Rpl_semi_sync_slave_status Value为ON。
#到此,MySQL半同步部署完成. 此时可以到master端查看运行状态了
mysql> show status like 'rpl%'; +--------------------------------------------+-------------+ | Variable_name | Value | +--------------------------------------------+-------------+ | Rpl_semi_sync_master_clients | 1 | | 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 | | 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 | 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 | | Rpl_status | AUTH_MASTER | +--------------------------------------------+-------------+ 15 rows in set (0.00 sec) # 关键看Rpl_semi_sync_master_status
# 为了下次开机自动启用半同步,还需要在配置文件中添加以下几行
Master上: [mysqld] rpl_semi_sync_master_enabled=1 rpl_semi_sync_master_timeout=1000 Slave上: [mysqld] rpl_semi_sync_slave_enabled=1
状态参数说明:
Rpl_semi_sync_master_clients
支持记录半同步slave的个数。
Rpl_semi_sync_master_net_avg_wait_time
master 等待slave 回复的平均等待时间。 单位毫秒.
Rpl_semi_sync_master_net_wait_time
master 总的等待时间。
Rpl_semi_sync_master_net_waits
master 等待slave 回复的的总的等待次数。
Rpl_semi_sync_master_no_times
master 关闭半同步复制的次数。
Rpl_semi_sync_master_no_tx
master 等待超时的次数
Rpl_semi_sync_master_status
标记master现在是否是半同步复制状态。
Rpl_semi_sync_master_timefunc_failures
记录master调用类似 gettimeofday()等函数的失败次数
Rpl_semi_sync_master_tx_avg_wait_time
master 花在每个事务上的平均等待时间。
Rpl_semi_sync_master_tx_wait_time
master 华仔所有事物上的等待时间
Rpl_semi_sync_master_tx_waits
master总的等待次数
Rpl_semi_sync_master_wait_pos_backtraverse
Rpl_semi_sync_master_wait_sessions
当前有多少个session 因为slave 的回复而造成等待
Rpl_semi_sync_master_yes_tx
master 成功接收到slave的回复的次数。
总结:完成MySQL主从的半同步部署,实际上只有几步
# Master mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; mysql> set global rpl_semi_sync_master_enabled=1; mysql> set global rpl_semi_sync_master_timeout=1000; mysql> show status like 'rpl%';
# Slave mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; mysql> set global rpl_semi_sync_slave_enabled=1; mysql> show status like 'rpl%';