首页 / 数据库 / MySQL / MySQL主从复制中断报error code=1217错误解决
MySQL主从复制中断,报“Error on master: message (format)="Cannot delete or update a parent row: a foreign key constraint fails" 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修复,具体未测。本文永久更新链接地址