阿里云首页 云数据库 RDS

RDS MySQL只读实例同步延迟原因与处理

问题描述

由于阿里云云数据库RDS只读实例采用MySQL原生的基于Binlog的复制技术(异步复制或半异步复制),必然会有同步延迟。延迟会导致只读实例与主实例的数据出现不一致,从而导致业务出现问题。另外延迟也有可能引起Binlog堆积,导致只读实例空间被迅速消耗。本文介绍常见的导致延迟时间变长的场景。

说明:若主实例正产生大量的Binlog,这种情况下有可能会使只读实例被锁定。

问题原因

常见的几种导致延迟时间变长的问题原因如下:

  • 只读实例规格过小
    这类延迟场景经常出现在只读实例规格和主实例规格相差较大,而且只读实例负载较重的情况下,例如只读实例IOPS过高。只读实例为了和主实例保持同步,采用了MySQL原生的Binlog复制技术,由一个IO线程和一个SQL线程来完成。IO线程负责将主实例的Binlog拉取到只读实例,SQL线程负责将这些Binlog日志应用到只读实例。这两个线程会消耗只读实例的IO资源,所以当只读实例的IOPS配置不高时,会导致只读实例数据延迟。您可以登录RDS控制台,通过监控信息确认IOPS较高。
  • 主实例的TPS(Transaction Per Second)过高
    由于只读实例与主实例之前的同步采用的是单线程同步,若主实例并发多线程写入数据,在主实例TPS过高的情况下容易出现只读实例的数据延迟,您可以通过观察只读实例的TPS与主实例的TPS性能数据来判断。
  • 主实例的大事务

    主实例执行一个涉及数据量非常大的update、delete、insert…select、replace…select等事务操作时,会生成大量的Binlog数据并同步到只读实例。只读实例需要花费与主实例相同的时间来完成该事务,因此会导致只读实例同步延迟。例如在主实例上执行一个持续80秒的删除操作,只读实例进行相同操作时也需要花费很长时间,于是会出现延迟情况。

  • 主实例的DDL语句执行时间较长
    • 只读实例和主实例数据同步是串行进行的,如果DDL操作在主实例执行时间很长,那么同样在只读实例也会消耗同样的时间导致延迟。常见操作例如create index、repair table、alter table add column等。
    • 只读实例上执行的查询或未完成的事务阻塞了来自主实例的DDL执行。

解决方案

阿里云提醒您:

  • 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。
  • 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。
  • 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。

排查方法

当只读实例出现延迟时,可以根据以下排查方法定位问题:

  • 在RDS控制台中查看监控信息,检查只读实例的IOPS,确认只读实例是否存在资源瓶颈。
  • 在RDS控制台查看监控信息,检查只读实例的TPS,确认主实例TPS是否过高。
  • 检查只读实例的Binlog增长量,确定是否存在大事务。
  • 查看慢日志信息,确认是否存在alter,repair和create等DDL操作,详情请参见分析慢日志
  • 只读实例执行show slave status \G命令,确定是否存在元数据锁。
  • 检查只读实例是否存在无主键表的删除或者更新操作,可以通过在只读实例上执行show engine innodb status\G语句查看,或者执行show open tables语句后,查看输出结果的in_use列的值为1的表。

解决方法

本节列出以下四种常见的解决方法,您可以根据排查方法定位的问题原因选择对应的解决方法:

只读实例规格过小

建议您升级只读实例规格,使只读实例的配置大于或者等于主实例的配置,避免由于只读实例规格较小导致延迟,详情请参见变更配置

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

确认主实例的TPS是否正常,如果TPS过高,则需要对业务进行优化或者拆分,保证主实例的TPS不会导致只读实例出现延迟。TPS相关数据可以通过自治服务的性能趋势页面查看,详情请参见性能趋势

主实例的大事务

  1. 在只读实例出现大事务导致延迟时,登录数据库,执行以下SQL语句,确认Seconds_Behind_Master不断变化,而Exec_Master_Log_Pos却保持不变,说明只读实例的SQL线程在执行一个大事务或者DDL操作。然后通过show processlist语句定位具体的线程。
    show slave status \G
    系统显示类似如下。
    主实例执行大事务
  2. 建议您将大事务拆分为小事务分别执行。例如在delete语句中增加where条件子句,限制每次删除的数据量,将一次删除操作拆分为多次数据量较小的删除操作进行。这样只读实例可以迅速的完成事务的执行,不会造成数据的延迟。

主实例的DDL语句执行时间长

  • 对于DDL直接引起的只读实例延迟,建议在业务低峰期执行这些DDL。
  • 对于来自主实例的DDL语句在只读实例上被阻塞的情况
    1. 需要在只读实例上执行show processlist语句,确认SQL线程的状态为“waiting for table metadata lock”。
    2. 然后使用kill命令终止只读实例上引起阻塞的会话,恢复只读实例和主实例的数据同步,详情请参见解决MDL锁导致无法操作数据库的问题

更多信息

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

适用于

  • 云数据库RDS MySQL版
首页 云数据库 RDS 常见问题 只读实例/读写分离 RDS MySQL只读实例同步延迟原因与处理