Mysql 异步复制延迟的原因及解决方案

在异步或半同步的复制结构中,从库出现延迟是一件十分正常的事。虽出现延迟正常,但是否需要关注,则一般是由业务来评估。
 

复制逻辑过程


1、主库将对数据库实例的变更记录到binlog中。 (此过程不会产生延迟)
2、主库会有binlog dump线程实时监测binlog的变更并将这些新的events推给从库(Master has sent all binlog to slave; waiting for more updates)(日志量越大,延迟越久)
3、从库的IO Thread接收这些events,并将其记录入relaylog。(日志量越大,网络传输时间越长,延迟越久)
4、从库的SQL Thread读取relaylog的events,并将这些events应用(或称为重放)到从库实例。(通常是造成延迟的主要过程)

 

如何判断延迟时长

在从库上执行SHOW SLAVE STATUS\G ;检查Seconds_Behind_Master值即可.

此方法的结果有一定的偏差,如果要求不是非常严格的话,使用是没有问题,要求严格的话,可以使用pt工具检查。

 

造成延迟的主要原因

MySQL的主从复制都是单线程的操作,主库对所有DDL和DML产生的日志写进binlog,由于binlog是顺序写,所以效率很高。Slave的SQL Thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是随即的,不是顺序的,成本高很多。另一方面,由于SQL Thread也是单线程的,当主库的并发较高时,产生的DML数量超过slave的SQL Thread所能处理的速度,或者当slave中有大型query语句产生了锁等待那么延时就产生了。(虽然5.7有并行复制功能,不过在大并发的情况下,从库并行度肯定会比主库低)

常见原因:Master负载过高、Slave负载过高、网络延迟、机器性能太低、MySQL配置不合理。

 

解决延迟的办法

1.升级数据库版本到5.7以上,开启并行复制,加大并行复制线程数到适合的个数

2.避免在主库上执行大的事务,将大事务拆分成小事务。

3.关闭从库binlog,修改innodb_flush_log_at_trx_commit配置。

4.确保每个表都是显示的递增主键,避免从库更新或删除时扫描全表。

5.根据从库上业务情况,可适当减小大表的索引个数,以减小每次操作时索引维护的开销。

6.如果业务允许,只复制部分库表数据。

7.减少从库上的操作,减小从库压力。

8.增加从库所在服务器的硬件配置。

9.优化网络,尽量内网复制