当前位置:Gxlcms > 数据库问题 > MySQL复制异常大扫盲:快速溯源与排查错误全解

MySQL复制异常大扫盲:快速溯源与排查错误全解

时间:2021-07-01 10:21:17 帮助过:13人阅读





(3)原因分析过程


查看error log

Error log中显示的详细错误信息如下:



错误信息显示无法找到对应的binlog文件。


查看主库binlog日志

查看主库的binlog日志文件列表,可能会发现主库的binlog变成重新开始记录:



或者需要复制的binlog已经被删除:




总结

如果binlog重新开始记录,通常是由于主库执行了reset master命令,导致所有的binlog被删除。

如果binlog任然在继续记录,只是从库需要的binlog被删除,通常是由于主库手动执行了purge binary logs命令,或者日志的保留时间超过了expire_logs_days设置的时间。

3、从库没有执行主库复制的语句

由于GTID的特性,SQL线程不会去执行相同的GTID对应的事务,即如果SQL线程发现从relay log中读取到的事务对应的GTID已经存在于从库的GTID_EXECUTED中,那么SQL线程便不会存在。

(1)错误原因

复制过程中,用于主库执行的事务对应的GTID已经存在于从库的GTID_EXECUTED中,那么从库便不会执行这些事务,从而导致主库和从库的数据不一致。通常有如下情况:

主机执行了reset master(从库当前读取主机的第一个binlog,并不会因为reset master而导致找不到文件)
重做主从,从库没有清除从库的binlog

(2)错误信息

在从库忽略主机执行的事务的过程中,从库复制不会报出任何错误,所以这种复制的异常容易被忽略,没有办法及时的发现。

由于主库和从库的数据库不一致,后续的DML和DDL操作可能会发生执行失败的错误。

(3)原因分析过程

这里我们以插入语句找不到对应的表为例。


查看error log

Error log中记录错误信息:




查看show slave status

show slave status显示的信息全部正常,无从库执行事务的binlog产生。这里不排除从库关闭binlog执行drop table操作的可能。


查看表

分别在主机和从库执行命令show create table mydb.mytbl4,发现从库上并未不存在mydb.mytbl4。

(4)解析binlog日志

解析主机binlog日志,查看建表的事务日志:



解析从库的binlog日志,查找是否存在建表的事务日志:



这时我们发现对于相同的GTID,从库和主机执行的语句是不相同的。

(5)总结

通过上述分析,我们推断是从库并没有执行建表语句,从而导致主库数据不一致。

(6)说明

这种情况在mysql-5.7版本会在复制时有更严格的校验,如果主机发送GTID要少于从库的GTID,那么会报告出如下的错误:



但是即使在5.7版本,如果启动复制的时(错误后重新启动),主库执行的GTID超过了从库,仍然会报出同样的错误。

4、主库执行了不进行复制的语句

(1)错误原因

主库上执行的操作并不会写入binlog。这里不考虑主库主动关闭binlog的情况。

(2)错误信息

由于主库和从库的数据不一致,从而导致主库执行的操作复制到从库后,发生从库执行失败的情况。如:

创建FEDERATED引擎的表失败



(3)原因分析过程

这里以使用CONNECTION创建FEDERATED引擎的表为例。


查看error log

Error log中记录错误信息:




查看主库和从库的server表

主库中server表中存在名字为s的记录:



从库中不存在名字为s的记录:




查看CREATE SERVER文档说明

文档中记录,create server语句并不会记录到binlog中。所以导致了主库和从库的数据不一致。复制无法正常进行。


总结

对于不记入binlog的操作,需要主库和从库同时执行,以防发生主库和从库不一致的情况。

5、从库重复执行relay log的语句(非GTID,非多线程复制)

当变量relay_log_info_repository设置为FILE时,从库的SQL线程每次执行完一个事务后,会把对应的文件和位置信息更新到文件relay_log.info中。用于在从库重启时,SQL能够从正确的位置继续进行复制。

(1)错误原因

如果物理机发生宕机或者从库发生意外中断,那么可能发生SQL线程已经执行过了某一个relay log中的事务,但是这个事务对应文件和位置信息并没有及时更新到relay_log.info中的情况。在从库发生重启之后,会将执行过的事务重新再次执行。

(2)错误信息

重复执行的事务包括任何记录到relay log中的事务,可能出现的错误信息包括:

创建库或者表失败:



插入语句主键冲突:



删除语句找不到对应的语句:



由于各种类型的事务均可能执行,这里不再一一列举。

(3)原因分析过程

这里以插入语句主键冲突为例。


查看error log

Error log中记录以下报错信息:



可以看到是SQL线程在启动后执行的第一个事务就发生主键冲突的错误。


查看show slave status

show slave status显示的信息全部正常,无从库执行事务的binlog产生。


查看表mydb.k2

表中已经存在了这条记录。


查看从库的relay log和binlog

查看从库的relay log,从复制的起始位置./relaylog002.000002:616查看



查看从库的binlog:




总结

通过分析上述binlog内容,relay log中并没有记录相同的insert语句,而从库的binlog显示已经执行过该语句,当从库重启后,试图再次执行相同的insert语句,从而导致插入语句的主键冲突。


说明

如果复制使用GTID,那么GTID的特性会使从库不执行相同的语句。
如果在5.7版本复制使用多线程复制,那么mts_recovery会修复这个问题。
只有在非多线程复制、非GTID复制的情况下才可能出现这个错误。

五、总结

如果复制发生了错误,通过收集上述的复制相关信息和错误相关信息,分析这些信息中与正常复制异常的地方,便可为排查复制错误提供更多的可以用来排除异常的信息。

当然复制的错误是多种多样的,并不是所有的错误都可以排查到具体的产生原因。很多复制错误是较难或者无法进行排查的,比如主库或者从库的binlog日志文件已经丢失、比如关闭binlog后执行某些操作导致复制不一致,再比如某些内核BUG导致MySQL的复制逻辑本身发生了异常等。

MySQL复制异常大扫盲:快速溯源与排查错误全解

标签:报错   tps   停止   接收   master   定位   https   drop   日志   

人气教程排行