MySQL5.6 crash-safe replication一个坑

.版本

1)操作系统

cat /etc/issue
CentOS release 6.9 (Final)
Kernel \r on an \m

cat /proc/version
Linux version 2.6.32-696.el6.x86_64 (mockbuild@c1bm.rdu2.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) ) #1 SMP Tue Mar 21 19:29:05 UTC 2017

2)mysql数据库版本

mysql --version

mysql  Ver 14.14 Distrib 5.6.26, for linux-glibc2.5 (x86_64) using  EditLine wrapper

 

 

2. 问题描述

2.1 问题发现

    在测试crash-safe 功能时发现了点问题,如果我指定了 relay_log_info_repository = TABLE,这时主库执行DDL语句后,从库的 relay_log_info_repository 表中的 Master_log_pos 字段并不会立即被更新(这时ddl操作已经被应用到从库,并且从库show slave status\G; 查看执行的位置是正确的),而DML语句不会有该问题(sync_relay_log_info 为默认值 10000)。

    如果在主库执行了一个ddl,并且该ddl被从库应用后,紧接着(从库执行该ddl后)从库异常宕机。那么从库再启动后可能会把之前已经执行过的ddl再次执行一遍,导致复制异常 会遇到如下错误:
Error 'Duplicate column name 'name_1'' on query. Default database: 'test_shao'. Query: 'alter table test_4 add column name_1 varchar(20)'

2.2 问题原因

  我们知道,MySQL 5.6 针对复制功能提供了新特性: slave支持crash-safe. 该功能可以解决之前版本中系统异常断电可能导致的SQL thread 信息不准确的问题。##关于crash-safe 详细介绍请参见 MySQL5.6新特性之crash-safe slaves

    实现 从库 crash-safe需要在从库配置文件中添加如下两个参数,并重启实例

relay_log_info_repository = TABLE
relay_log_recovery = ON

    从库实现 crash-safe 的大概原理就是把 sql_thread 的执行位置记录到 innodb 表中(relay_log_info_repository = TABLE),并且把 sql_thread 线程执行事务和更新 mysql.slave_relay_log_info 放在一个事物中,从而避免实际已执行的binlog位点和写入relay log info 的位点信息不一致的情况发生。那的怎么保证 io_thread 线程位点的正确性,通过添加 relay_log_recovery = ON 参数,在从库实例重启时会自动把 io_thread 线程位点初始化成 sql_thread位点。

##对于dml 我们可以做到把 dml操作 和 mysql.slave_relay_log_info表的更新放到一个事务中来保证位点正确性,那么对于 ddl 操作呢?

2.3 问题处理
如果我指定了 relay_log_info_repository = TABLE,这时主库执行DDL语句后,从库的 relay_log_info_repository 表中的 Master_log_pos 字段并不会立即被更新(这时ddl操作已经被应用到从库,并且从库show slave status\G; 查看执行的位置是正确的),而DML语句不会有该问题。这时有如下几种情况会让从库的 relay_log_info_repository表信息更新到最新值
1)如果此时主库再执行一个dml操作,我们会发现从库 relay_log_info_repository 中记录的位置被更新为最新值。


2)重启复制线程 stop slave; start slave;


3)设置 从库 sync_relay_log_info = 1

##官方文档中说到 如果 relay_log_info_repository = TABLE, 对于支持事务的存储引擎来说,会忽略 sync_relay_log_info 该参数,但是实测 发现对于 ddl 如果 sync_relay_log_info 大于 1,则 mysql.slave_relay_log_info 表中 主库binlog 位置不会及时刷新。设置为1 时会及时刷新。

4)如果你确定ddl语句已经在从库执行,那你可以 set global sql_slave_skip_counter=1; 跳过该错误,修复主库复制
 

##综上所述,如果你 设置了 relay_log_info_repository = TABLE,建议同时设置 sync_relay_log_info = 1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

渔夫数据库笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值