华为云云数据库rdsMySQL主备复制延迟场景及解决方案_云淘科技
RDS for MySQL的默认备库、只读实例、自建从库、DRS链路灾备实例均基于MySQL的Binlog复制技术,也称为MySQL主备复制或主从复制技术。主备复制实现又分为异步复制或半同步复制,无论哪种方式,由于业务执行的语句的原因,不可避免的存在主备复制延迟。
现象表现为:RDS for MySQL备机或只读存在复制时延过高,甚至产生复制时延大的告警。
场景1:主库执行了大事务
大事务一般指一个事务中包含大量的数据更新操作,例如一个事务包含几万次DML(insert,update,delete)操作、一条SQL语句批量更新了上万行数据等,大事务往往本身的执行时间很长(分钟级)。当主实例执行了大事务后,会产生大量的Binlog日志,备机或只读节点拉取这些Binlog耗时比一般事务长,且至少需要花费与主实例相同的时间来回放这些事务的更新,从而导致备机或只读节点出现复制延迟。
排查方法:
对于包含大量DML语句的大事务,使用如下命令,找到长时间执行的事务。
select t.*,to_seconds(now())-to_seconds(t.trx_started) idle_time from INFORMATION_SCHEMA.INNODB_TRX t \G;
对于一条SQL语句执行大量数据的大事务,执行show full processlist,查找是否存在长时间执行的delete或update语句。
分析全量日志或慢日志,检查是否有大事务。
解决方法:
为了保证主从数据的一致性,需要等待大事务执行完成,主备复制延迟才能恢复。
业务侧避免此类大事务,可以将大事务拆分为小事务,分批执行。例如,通过where条件或limit语句限制每次要更新的数据量。
场景2:对无主键表更新
RDS for MySQL的Binlog采用row格式,对每一行的数据更新,都会形成row格式Binlog event记录。例如:一个update语句更新100行数据,那么row格式的Binlog中会形成100行update记录,备机或只读回放时会执行100次单行update。
只读节点和备机在回放主库的Binlog event时,会根据表的主键或者二级索引来检索需要更改的行。如果对应表未创建主键,则会产生大量的全表扫描,从而降低了Binlog日志的应用速度,产生复制延迟。
排查方法:
通过show create table xxx,分析执行慢的update和delete语句对应的表,分析是否有主键。
解决方法:
给无主键表增加主键,给缺少二级索引的表增加索引。
场景3:DDL操作
DDL操作往往执行时间很长,尤其是表数据量很大时。通常情况下,只读节点或备机回放一个DDL操作的时间和主库花费的时间基本一致。因此,当主机执行了大表的DDL操作后,备机和只读节点在回放该DDL期间,复制时间必然是一致增大的。
解决方法:
该场景为正常现象,等DDL执行完成后,主备复制延迟才能恢复。建议在业务低峰期执行DDL操作。
场景4:只读实例等待MDL锁
只读实例上往往有业务流量,如果存在只读长事务正在执行,会阻塞主实例同步过来的相应表的DDL操作,卡在了表MDL锁获取,进而阻塞所有同表的后续Binlog回放,导致复制延迟越来越大。
排查方法:
登录只读节点,使用如下命令,观察是否有长时间执行的事务。
select t.*,to_seconds(now())-to_seconds(t.trx_started) idle_time from INFORMATION_SCHEMA.INNODB_TRX t \G;
查看只读节点的MDL锁视图,观察是否有MDL锁冲突。
select * from information_schema.metadata_lock_info;
根据MDL锁视图中的线程ID,找到阻塞的session。更多信息,请参见MDL锁视图。
解决方法:
kill只读节点上阻塞DDL操作的长事务,或者在业务侧提交该长事务。
场景5:只读实例规格小于主实例
只读实例、DRS灾备实例的规格小于主实例时,一旦主实例写负载升高到一定程度,只读实例或DRS灾备实例会因为自身资源不足,无法及时回放Binlog,导致复制时延增加。
解决方法:
只读实例或DRS灾备实例扩大规格,与主实例规格匹配。
场景6:读业务压力突然增大
只读库除了要同步主库的数据之外还要承担数据读的业务,当读业务压力突增时,可能会影响只读的回放线程,从而导致只读复制时延增加。
父主题: 主备复制
同意关联代理商云淘科技,购买华为云产品更优惠(QQ 78315851)
内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家