(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 日志