MySQL半同步介绍
一般情况下MySQL默认复制模式为异步,何为异步?简单的说就是主服务器上的I/O threads 将binlog写入二进制日志中就返回给客户端一个结果,无需等待二进制日志是否成功发送到从库和从库上是否成功完成relay log的写入以及SQL threads从relay log中提取二进制日志写入自己binlog的过程,异步模式的缺点就是一旦主库写入binlog日志后发生宕机,此时从库还未完成对主库传送过来binlog的读写存储操作,那么从库就会发生数据丢失的现象。所以这里就出现了另外一种复制模式,即半同步模式。
在半同步模式下,主库将binlog日志信息写入到日志中,然后等待从库完成后面的接收读取和存储操作,并返回主库一个明确信息,即从库接收完主库传递过来的binlog内容已经写入到自己的relay log中,才会通知主库上的等待线程,该操作已经完成,此时主库接收到从库发过来的信息就会进入下一个同步操作动作,如果在此时等待超时,超过主库中设置的超时时间限制(一般是rpl_semi_sync_master_timeout的值),则关闭半同步,并切换为异步模式,直到至少有一台从库告诉主库已经接收到主库传送过来的binlog信息为止。
MySQL半同步特点
1、从库会在连接到主库时告诉主库,它是不是匹配了半同步
2、如果半同步在主库端是开启了的,并且至少有一个半同步复制的从库节点,那么此时主库的事务线程在提交时会被阻塞并等待,结果有两种可能:要么至少有一个从库节点通知它已经收到了这个事务的binlog事件,要么一直等待到超时直至到我们配置的某一个时间点为止,而此时,半同步复制将自行关闭,转换为异步复制模式
3、从库节点只有在接收到某一个事务的所有binlog将其写入并Flash到Relay Log文件之后,才会通知对应主库上的等待线程。
4、如果在等待过程中,主库等待的时间已经超过了配置的超时时间,没有任何一个从库节点通知当前事务,那么此时主库会自动转换为异步复制模式,如果当前只要有一个同步从节点赶上来,主库便会又自动转换为半同步复制方式。
5、半同步模式必须在主库和从库上都开启,如果主库上没打开,或者在主库上开启而从库没开启,主库都会使用异步模式复制。
搭建
半同步复制模式提高了主从之间数据的一致性,让复制更加安全,从MySQL5.7版本以后,又增加了rpl_semi_rsyn_master_wait_point
参数,用来控制半同步模式下主库在返回给session事务成功之前的事务提交方式,该参数有两个值:
AFTER_COMMIT
:
该值是MySQL5.6版本的默认值,主要意思是主库将每个事务写入binlog,并传递给从库,刷新到中继日志中,同时主库提交事务。之后主库开始等待从库的反馈,只有收到从库 的回复,master才将“commit OK” 的结果返回给客户端。
AFTER_SYNC
:
该值的是MySQL5.7版本之后新增的,也是在MySQL5.7默认的半同步复制方式。主要意思是主库将每个事务写入自己的binlog并传递给从库,刷新到中继日志中,主库开始等待从库的反馈,当主库接收到从库的回复之后,再提交事务并返回”commit Ok”结果给客户端。
注:可以通过
rpl_semi_sync_master_wait_for_slave_count
参数来控制主库接收多少个从库写事务成功反馈,才返回成功给客户端。生产环境中使用半同步复制,当从库出现故障,等待超时的时间又很长,导致主库无法接收从库信息而无法正常写入时,可以通过该参数踢出故障从库。
在after_sync模式下,即使主库宕机,所有在主库上已经提交的事务都能保证已经同步到从库的中继日志中,不会丢失任何数据。
半同步复制的搭建环境很简单,它是基于异步复制的基础上,安装不同步复制插件就可以了。
主库上操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; mysql> set global rpl_semi_sync_master_enabled=on; mysql> show variables like '%semi%'; +-------------------------------------------+------------+ | 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 | +-------------------------------------------+------------+ 6 rows in set (0.01 sec) |
注:还有一个比较重要的参数就是
rpl_semi_sync_master_timeout
,单位是毫秒。它表示如果主库等待从库回复消息的时间超过该值,就自动切换为异步复制模式。建议不要取默认值10s,该值可以调整得很大,禁止向异步复制切换来保证数据复制的安全性。MySQL5.7半同步复制默认的方式就是after_sync模式。
1 2 3 4 5 6 7 |
mysql> show plugins; +----------------------------+----------+--------------------+--------------------+---------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+--------------------+---------+ | rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL | +----------------------------+----------+--------------------+--------------------+---------+ 45 rows in set (0.00 sec) |
然后再在从库中安装半同步复制插件和开启半同步复制功能:
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; mysql> set global rpl_semi_sync_slave_enabled=on; mysql> show variables like '%semi%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 2 rows in set (0.01 sec) |
通过show plugins
确认插件已经加载成功:
1 2 3 4 5 6 |
mysql> show plugins; +----------------------------+----------+--------------------+-------------------+---------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+-------------------+---------+ | rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL | +----------------------------+----------+--------------------+-------------------+---------+ |
注:为了以后可以开机自启动半同步复制功能,我们可以把
rpl_semi_sync_slave_enabled=on
、rpl_semi_sync_master_enabled=on
两个参数加载到my.cnf配置文件中
因为以前已经开始了异步复制模式,现在只需要加载半同步复制的插件和启动半同步复制功能即可,所以接下来重启I/O threads,激活半同步复制。
1 2 3 |
mysql> stop slave io_thread; mysql> start slave io_thread; |
主库上查看半同步复制是否正常运行:
1 2 3 4 5 6 7 8 |
mysql> show global status like '%semi%'; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | Rpl_semi_sync_master_status | ON | +--------------------------------------------+-------+ 14 rows in set (0.04 sec) |
Rpl_semi_sync_master_clients
:参数代表已经有一个从库连接到了主库,并且是半同步复制方式。
Rpl_semi_sync_master_status
:参数是ON(开启)状态,代表已经是半同步复制模式了。
Rpl_semi_sync_master_no_tx
:代表没有成功接收slave提交的数据
Rpl_semi_sync_master_yes_tx
:代表成功接收slave事务回复的次数
在从库上查看半同步复制状态:
1 2 3 4 5 6 7 |
mysql> show global status like '%semi%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Rpl_semi_sync_slave_status | ON | +----------------------------+-------+ 1 row in set (0.00 sec) |
Rpl_semi_sync_slave_status
:参数等于on代表从库也开启了半同步复制模式,至此MySQL半同步复制搭建成功。