relay-log-info
记录SQL线程读取Master binlog的位置,用于Slave 宕机后根据文件中记录的pos点恢复Sql线程
master-info
记录IO线程读取已经读取到的master binlog位置,用于slave宕机后IO线程根据文件中的POS点重新拉取binlog日志
sync_relay_log_info
执行多少个事务后将relay-log-info,sync一下文件刷新到磁盘
sync_master_info
执行多少个事务后将master-info,sync一下文件刷新到磁盘
所以问题来了,如果下面两个sync参数设置较大,当宕机时:
- sync_master_info较大将导致重复拉取binlog日志
- sync_relay_log_info较大将导致重复执行binlog日志
那么设置两个参数为1
sync_master_info=1
sync_relay_log_info=1
是否解决问题了呢?
那么,请考虑如下场景
正常跑的slave突然掉电,最后一个事务已经commit成功了。但是可能还没有将sync_relay_log_info sync到磁盘上。因为sync文件这个动作不是在事务中,所以不能得到保证。当slave恢复之后,读取relay_log_info文件。会将最后一个事务重新做一遍,导致主从数据不一致
问题的关键在于sync操作不是在事务里,所以mysql提供了两个参数
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| master_info_repository | TABLE |
| relay_log_info_repository | TABLE |
+---------------------------+-------+
这样记录SQL线程及IO线程的执行情况将记录在表中(slave_relay_log_info,slave_master_info),事务的原子性得到了保证。
这里查看一下,sync_relay_log_info与relay_log_info_repository参数间的关系
可以看到当relay_log_info_repository为TABLE时,对于事务来说,sync_relay_log_info参数没有作用了
为了简化设置,这里介绍一个参数
relay_log_recovery
参数含义:当slave重启之后会根据slave_relay_log_info重新创建一个文件,SQL线程会根据这个文件进行恢复复制,IO线程会读取SQL线程的POS点,根据这个POS点向主库申请拉取数据
所以最终只要设置如下两个参数即可
relay_log_info_repository = TABLE
relay_log_recovery = ON