MySQL 从库延迟原因以及分析

背景

在 MySQL 5.6 之前从库复制都是单线程的,因此当主库压力比较大,从库访问量也比较大的时候容易出现从库延迟的状况,以下列出了一些造成从库延迟的原因以及可能的解决办法。参考了淘宝内核月报的文章,这篇文章比较好

延迟的原因

1、内存配置过小或者 iops 配置(这个指的是 io capacity,sas 盘和 ssd 盘配置有区别)不当。

2、主库 TPS 过高。(从库单线程复制会遇到此问题)

3、主库的 DDL 操作 (alter,drop,repair,create)
1)主库的 DDL 操作,在主库上串行执行 10 分钟,到从库上也会串行执行 10 分钟,导致延迟
2)从库上有慢查,会阻塞来自主库的 DDL 操作,直到查询结束为止。通过 show processlist 可以看到复制线程处于 waiting for table metadata lock 状态
3)如果从库开了 query_cache ,主库下来的 SQL 也可能会遇到 Waiting for query cache lock 的情况,如图。

4、主库执行大事务导致延迟
比如在主库执行一个大的 update、delete、insert … select 的事务操作,产生大量的 binlog 传送到只读节点,只读节点需要花费与主库相同的时间来完成该事务操作,进而导致了只读节点的延迟。

只读实例发生延迟,在只读节点执行 show slave status 命令,可以通过两个关键的位点参数来判断只读实例上是否在执行大事务:Seconds_Behind_Master 不断增加,但是 Exec_Master_Log_Pos 却没有发生变化,这样则可以判断只读节点的SQL线程在执行一个大的事务或者DDL操作。

针对此类大事务延迟的场景,需要将大事务拆分成为小事务进行批量提交,这样只读节点就可以迅速的完成事务的执行,不会造成数据的延迟

5、其它情况,如对无主键表的删除。
用户在删除数据的时候,由于表主键的缺少,同时删除条件没有索引,或者删除的条件过滤性极差,导致 slave 出现 hang 住,会严重的影响生产环境的稳定性。因此在设计表结构的时候一定要为表加上主键,主键可以认为是 innodb 存储引擎的生命。以下为阿里的几个案例以及分析(本案例的生产环境的 binlog 为row 模式,对于 myisam 存储引擎也有同样的问题):
https://yq.aliyun.com/articles/9066
https://yq.aliyun.com/articles/27792?spm=5176.blog9066.yqblogcon1.10.oG6gRV (常见延迟问题)

总结

综上所述,当只读实例出现延迟后的排查思路

  • 看只读节点 IOPS 定位是否存在资源瓶颈
  • 看只读节点的 binlog 增长量定位是否存在大事务
  • 看只读节点的 comdml 性能指标,对比主节点的 comdml 定位是否是主库写入压力过高导致
  • 看只读节点 show full processlist,判断是否有 Waiting for table metadata lock 和 alter,repair,create 等 ddl 操作。

最佳实践

  • 使用 innodb 存储引擎
  • 只读实例的规格不低于主实例
  • 大事务拆分为小事务
  • 多个只读节点冗余
  • DDL 变更期间观察是否有大查询

你可能感兴趣的:(MySQL,数据库,复制)