阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MySQL主从复制中断报error code=1217错误解决

222次阅读
没有评论

共计 2389 个字符,预计需要花费 6 分钟才能阅读完成。

MySQL 主从复制中断,报“Error on master: message (format)=’Cannot delete or update a parent row: a foreign key constraint fails’ error code=1217”错误。

前几天,发现从库挂了,具体报错信息如下:

MySQL 主从复制中断报 error code=1217 错误解决

分析思路

1. 因为我采用的是选择性复制,只针对以下几个库进行复制:card,upay,deal,monitor,collect。所以,不太可能出现对于 sas_basic 的操作能复制到该从库上。

2. 整个架构是 1 主 2 从,且都是选择性复制,上面这个从库是直接复制 card,upay,deal,monitor,collect 这几个数据库的数据,而另外一个从库则是忽略上述库,如下所示:

    怀疑是在上述 schema 下,执行了 DROP TABLE IF EXISTS `sas_basic.old_channel_code` 操作。

3. 于是根据报错信息查看了主库 binlog 日志的内容,发现是在 sas_basic schema 下操作的。

    use `sas_basic`/*!*/;

困惑

针对 sas_basic 的操作为什么会反映到不复制它操作的从库上。

 

PS:根据上述报错信息,中途还怀疑主从库的外键定义不一致导致上述问题的产生,后来查看,发现主从库的外键定义是一致的。

原因

上次利用 set global sql_slave_skip_counter= 1 跳过后,今天又碰到了这个问题,深入其中,才发现这是 MySQL 的一个 bug:https://bugs.mysql.com/bug.php?id=77684

但是这个 bug 中涉及到的版本是 5.6.25, 5.6.27。而我生产数据库是 5.6.26。于是,在测试机上搭建环境,看能否重现问题。

重现现场

还是一主两从,其中一个从设置 replicate-ignore-db=test,另外一个从设置 replicate-do-db=test。

在主中执行以下语句:

CREATE DATABASE `db1`;

USE `db1`;

CREATE TABLE `table1` (`ID` bigint(20) primary key) ENGINE=InnoDB;

CREATE TABLE `table2` (`ID` bigint(20) NOT NULL AUTO_INCREMENT, `DIVISION_ID` bigint(20) DEFAULT NULL, PRIMARY KEY (`ID`), KEY `FK_TABLE1_DIVISION_1` (`DIVISION_ID`), CONSTRAINT `FK_TABLE1_DIVISION_1` FOREIGN KEY (`DIVISION_ID`) REFERENCES `table1` (`ID`) ON DELETE CASCADE ) ENGINE=InnoDB;

DROP TABLE IF EXISTS `table1`;

结果,replicate-ignore-db=test 这个从库中复制正常,但 replicate-do-db=test 这个从库的复制却出现问题。报如下错误:

 Last_SQL_Error: Query caused different errors on master and slave.    Error on master: message (format)=’Cannot delete or update a parent row: a foreign key constraint fails’ error code=1217 ; Error on slave: actual message=’no error’, error code=0. Default database: ‘db1’. Query: ‘DROP TABLE IF EXISTS `table1` /* generated by server */’
  Replicate_Ignore_Server_Ids:

完美重现现场。

提交这个 Bug 的哥们同时也给出了一种替代方案

Suggested fix:
The problem seems to be related to the “USE” above as the following works as expected:

CREATE DATABASE `db1`;
CREATE TABLE `db1`.`table1` (`ID` bigint(20) primary key) ENGINE=InnoDB;
CREATE TABLE `db1`.`table2` (`ID` bigint(20) NOT NULL AUTO_INCREMENT, `DIVISION_ID` bigint(20) DEFAULT NULL, PRIMARY KEY (`ID`), KEY `FK_TABLE1_DIVISION_1` (`DIVISION_ID`), CONSTRAINT `FK_TABLE1_DIVISION_1` FOREIGN KEY (`DIVISION_ID`) REFERENCES `db1`.`table1` (`ID`) ON DELETE CASCADE ) ENGINE=InnoDB;
DROP TABLE IF EXISTS `db1`.`table1`;

however if you add an USE `db1` after the CREATE DATABASE statement the replication error will follow.

即在其它 schema 中删除该表。

但经过测试,无论是在其它 schema 中执行该操作还是不指定数据库执行该操作,均会使得复制中断。

总结:

1. 该 Bug 不仅仅在 replicate-ignore-db 会触发,在 replicate-do-db 中也会触发。

2. 官方承诺会在 5.6.30 和 5.7.12 修复,具体未测。

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-05/131247.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计2389字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中