您好,欢迎访问一九零五行业门户网

MySQL5.6crash-safereplication一个坑

事情起因:唯品会一个dba找到我,说他们的slave掉电,再重启服务器以后,同步复制就挂了,报1032和1062错误,首先排查了在从库上没有写操作,之后询问了他们的参数。 这是他们的参数: sync_master_info=1sync_relay_log_info=1relay_log_info_repository=fi
事情起因:唯品会一个dba找到我,说他们的slave掉电,再重启服务器以后,同步复制就挂了,报1032和1062错误,首先排查了在从库上没有写操作,之后询问了他们的参数。
这是他们的参数:
sync_master_info = 1sync_relay_log_info = 1relay_log_info_repository = file
参数意思是:sql线程每次执行完了一个事务,就会记录在master.info和relay.info文件里。即:
start transaction;-- statement 1-- ...-- statement ncommit;-- update replication info files
由于在记录relay.info的时候宕机,relay.info未更新,机器重启恢复后会从之前的pos点再次执行,这样就执行了两条同样的sql,就会报1032和1062错误,同步就挂了。
于是我建议他们设置:
relay_log_info_repository = tablerelay_log_recovery = 1alter table mysql.slave_relay_log_info engine=innodb;
参数意思是:把relay.info改成记录在slave_relay_log_info表里,并改成innodb引擎,并开启relay_log_recovery中继日志自我修复功能。即:
start transaction;-- statement 1-- ...-- statement n-- update replication infocommit;
这样sql线程执行完事务后,立即会更新slave_relay_log_info表,如果在更新过程中宕机,事务会回滚,slave_relay_log_info表并不会记录同步的点,下次重新同步复制时,从之前的pos点再次执行。
看似很完美了,但之后我在虚拟机上做了测试,发现了一个bug:
即针对ddl语句,不会触发刷盘操作,而dml语句不会有该问题,也就是说slave_relay_log_info表不会更新,必须手工执行stop slave;start slave;该表才会强制刷新。
试想一下,你修改了表结构以后,突然宕机,slave_relay_log_info表没刷进磁盘,下次重启服务后,会再次执行一次修改表结构,此时同步就挂了,你只能手工去跳过这个错误。
我测试的版本是:5.6.22-71.0-log percona server (gpl), release 71.0, revision 726
参考:
650) this.width=650; src=http://www.68idc.cn/help/uploads/allimg/151111/121515b24-0.jpg title=qq图片20150227181347.png alt=wkiol1twrldxnbh0aanu0nf7cyi259.jpg>
其它类似信息

推荐信息