如果一条语句在源和副本上产生相同的错误(相同的错误代码),则会记录错误,但复制会继续。
如果一条语句在源和副本上产生不同的错误,则复制 SQL 线程终止,并且副本将一条消息写入其错误日志并等待数据库管理员决定如何处理该错误。这包括语句在源或副本上产生错误的情况,但不能同时在两者上产生错误。要解决此问题,请手动连接到副本并确定问题的原因。 SHOW REPLICA STATUS(或在 MySQL 8.0.22 之前, SHOW SLAVE STATUS)对此很有用。然后修复问题并运行START REPLICA(或在 MySQL 8.0.22 之前 START SLAVE)。例如,您可能需要先创建一个不存在的表,然后才能再次启动副本。
笔记
如果在副本的错误日志中记录了临时错误,则您不必采取引用错误消息中建议的任何操作。临时错误应由重试事务的客户端处理。例如,如果复制 SQL 线程记录了与死锁相关的临时错误,则无需在副本上手动重新启动事务,除非复制 SQL 线程随后以非临时错误消息终止。
如果此错误代码验证行为不可取,则可以使用该 --slave-skip-errors选项屏蔽(忽略)部分或所有错误。
对于诸如 之类的非事务性存储引擎 MyISAM,可能会有一条语句仅部分更新表并返回错误代码。例如,这可能发生在多行插入中,其中一行违反了键约束,或者在更新某些行后终止了长更新语句。如果在源上发生这种情况,则副本期望语句的执行导致相同的错误代码。如果没有,复制 SQL 线程将如前所述停止。
如果您在源和副本上使用不同存储引擎的表之间进行复制,请记住,同一语句在针对表的一个版本运行时可能会产生不同的错误,而对另一个版本则不会,或者可能导致其中一个版本出错表的版本,但不是其他的。例如,由于MyISAM忽略了外键约束,访问源上的表的INSERTor UPDATE语句 InnoDB可能会导致外键违规,但在 MyISAM副本上的同一表的版本上执行的相同语句不会产生此类错误,从而导致复制停止。
从 MySQL 8.0.31 开始,在进行任何特权或行格式检查之前,首先应用复制过滤规则,从而可以过滤掉任何未通过验证的事务;不执行任何检查,因此不会为已过滤掉的事务引发错误。这意味着副本只能接受给定用户已被授予访问权限的那部分数据库(只要对这部分数据库的任何更新都使用基于行的复制格式)。这在执行升级或迁移到使用入站复制用户无权访问的管理表的系统或应用程序时可能会有所帮助。也可以看看第 17.2.5 节,“服务器如何评估复制过滤规则”。




