添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1. 只读实例产生延迟的原因

1.1 只读实例规格过小

1.2 主实例的 TPS(Transaction Per Second)过高

1.3 主实例的大事务

1.4 主实例的 DDL 语句

1.5 只读实例 MyISAM 引擎表

1.6 其他

2. 综述


RDS MySQL只读实例通常用于分担主实例的查询(Select)压力,或者用于运行 OLAP 类型的分析应用,避免复杂统计查询对主实例的性能影响。

RDS MySQL 只读实例架构图:

read_only_01.png

由于 RDS 只读实例采用 MySQL 原生的基于 Binlog 的复制技术(异步复制或半异步复制),那么延迟必然会成为成立之初就存在的问题。

延迟会导致只读实例与主实例的数据出现不一致的情况,进而可能造成业务上逻辑的混乱或者数据不正确。另外延迟也有可能引起 Binlog 数据堆积,导致只读实例空间被迅速消耗(如果主实例当前正产生大量的 Binlog 数据),这种情况下有可能会使只读实例被锁定。

1. 只读实例产生延迟的原因

1.1 只读实例规格过小

这类延迟场景经常出现在只读实例规格和主实例规格相差较大,而且只读实例上负载较重,比如只读实例上 IOPS 打满。

分析:

只读节点的数据为了和主节点保持同步,采用了 MySQL 原生的 binlog 复制技术,由一个 IO 线程和一个 SQL 线程来完成。IO 线程负责将主库的 binlog 拉取到只读节点,SQL 线程负责消费这些 binlog 日志应用到只读实例。 这两个线程会消耗只读节点的 IO 资源,所以当只读节点 IOPS 配置不够的时候,则会导致只读节点的数据出现延迟。

read_only_04.png

比如下面的例子: 只读实例的 IOPS 被查询打满,导致和主实例的数据同步出现延迟。

read_only_02.png

read_only_03.png

建议:

对于这样的情况,建议用户升级只读实例规格,避免由于只读实例规格较小导致数据延迟。RDS 推荐只读实例的配置大于或者等于主实例的配置。

1.2 主实例的 TPS(Transaction Per Second) 过高

主实例的 TPS (Insert、Update、Delete)过高导致只读节点延迟。

分析:

由于只读节点与主实例同步采用的是单线程同步,而主实例的压力是并发多线程写入,这样在主实例高并发 DML TPS 情况下非常容易出现只读实例的数据延迟,可以通过观察只读实例节点的TPS与 主实例的 TPS 性能数据来完成判断。

主实例的 TPS :

read_only_06.png

只读实例的 TPS:

read_only_05.png

只读实例的延迟:

read_only_07.png

建议:

排查主实例的写入压力是否正常;如果正常则需要对业务进行优化或者拆分,保证主实例的 TPS 不会导致只读实例出现延迟。

1.3 主实例的大事务

主实例执行一个大事务导致延迟。

分析:

比如在主实例执行一个涉及数据量非常大的 update、delete、insert...select、replace...select 等事务操作,生成大量的 binlog 数据传送到只读实例。只读实例需要花费与主实例相若的时间来完成该事务,进而导致了只读实例的同步延迟。

比如下面的例子,在主实例上执行一个持续 80 秒的删除操作,会导致只读实例上出现数据延迟。

read_only_09.png

只读实例数据延迟:

read_only_10.png

在只读实例出现大事务导致延迟时,通过 show slave status \G 命令,可以看到 Seconds_Behind_Master 不断变化,而 Exec_Master_Log_Pos 却保持不变,这样可以判断只读实例的 SQL 线程在执行一个大的事务或者DDL 操作。

read_only_11.png

read_only_12.png

建议:

建议考虑将大事务拆分为小事务(比如在 delete 语句中增加 where 条件子句,限制每次删除的数据量,将一次删除操作拆分为多次数据量较小的删除操作进行),这样只读实例可以迅速的完成事务的执行,不会造成数据的延迟。

1.4 主实例的 DDL 语句

主实例的 DDL(alter、drop、repair、create)导致只读实例延迟。

分析:

    只读实例和主实例数据同步是串行进行的,如果 DDL 操作在主实例执行时间很长,那么同样在只读实例也会消耗同样的时间。比如对一张 500 万行的表添加一个字段耗费了 10 分钟,那么在只读实例上同样也会耗费10 分钟。所以只读实例会延迟 600 秒。其他常见操作比如 create index、repair table、alter table add column 等。

主实例:

read_only_13.png

只读实例:

read_only_14.png

    只读实例上执行的查询或未完成的事务阻塞来自主实例的 DDL 执行。在只读实例上执行 show processlist 命令查看 SQL 线程的状态为:waiting for table metadata lock.

只读实例:

read_only_17.png

read_only_16.png

建议:

    对于DDL直接引起的只读实例延迟,建议这些 DDL 在业务低峰期执行。

    对于来自主实例的DDL在只读实例上被阻塞的情况,需要 kill 掉只读实例上引起阻塞的会话(通常是运行时间长的查询)来恢复只读实例和主实例的数据同步。

注:对于表原数据锁等待的原因和处理,请参考 RDS MySQL 表上Metadata lock 的产生和处理

1.5 只读实例 MyISAM 引擎表

只读实例上针对 MyISAM 引擎表的长时间查询,阻塞来自主实例对该表的数据同步,导致只读实例数据延迟。

分析:

MyISAM 引擎表读写相互冲突,同一时间读写不能并发操作,且仅支持表级锁。因此表上的长时间查询(比如 SQL 注入)会阻塞SQL线程应用来自主实例的该表数据变化,导致只读实例数据延迟。

主实例: 对 MyISAM 引擎表 large_tab_02插入数据。

read_only_18.png

只读实例:存在对表 large_tab_02 的长时间查询,使 SQL 应用线程等待 large_tab_02 表级锁,导致数据步发生延迟。

read_only_21.png

read_only_22.png

read_only_23.png

read_only_20.png

建议:

如果使用只读实例,建议业务低峰期将主实例上的 MyISAM 引擎表转换为 InnoDB 引擎表(只读实例上会相应进行转换)。

1.6 其他

其他只读实例出现延迟的情况:

比如只读实例的主机 IO 压力出现异常,或者对无主键的表进行删除(RDS目前已经支持对表添加隐式主键,但是对于以前历史创建的表需要进行重建才能支持隐式主键)。

2. 综述

综上所述,把目前RDS只读实例出现延迟的场景都进行了分析,可以简单归纳一下:

当只读实例出现延迟后,

一看只读节点 IOPS 定位是否存在资源瓶颈;

二看只读节点的 binlog 增长量定位是否存在大事务;

三看只读节点的 ComDML 性能指标,对比主节点的 ComDML 定位是否是主库写入压力过高导致;

四看只读节点执行 show slave status \G,判断是否有 Waiting for table metadata lock;同时在主实例控制台 =》SQL明细 中排查下是否有 alter,repair,create等 DDL 操作;

五看只读节点执行 show slave status \G,判断是否有 Waiting for table level lock; 同时通过 show full processlist; 或者 DMS =》 实例信息 =》 实例会话 检查下是否有长时间对 MyISAM 引擎表的查询。

如果上述五看都还没有发现问题,那么在最后再检查一下只读节点是否存在 无主键表 的删除或者更新操作,可以通过在只读节点执行:show engine innodb status\G 或者 show open tables 状态为 in_use 为1的表:

mysql> show open tables;
+-------------------+-----------------------+-------------+------------------+
| Database          | Table                 | In_use      | Name_ locked     |
+-------------------+-----------------------+-------------+------------------+
| aixuedai_web      | sd_repay              |         4   |               0  |
| mysql             | slow_log              |         0   |               0  |
| dw                | dw_acc_sd_expectpay   |         1   |               0  |

如问题还未解决,请联系 售后技术支持