欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL数据库主从复制延时超长的解决方法

程序员文章站 2023-11-28 10:03:34
前言 mysql主从复制的延时一直是业界困扰已久的问题。延时的出现会降低主从读写分离的价值,不利于数据实时性较高的业务使用mysql。 udb是ucloud推出的云数据...

前言

mysql主从复制的延时一直是业界困扰已久的问题。延时的出现会降低主从读写分离的价值,不利于数据实时性较高的业务使用mysql。

udb是ucloud推出的云数据库服务,上线已达六年,运营了数以万计的udb mysql实例。除了提供高可用、高性能、便捷易用的产品特性,团队还平均每天帮助用户解决2-3起mysql实例主从复制延时的问题。从大量实践中我们总结了主从复制延时的各种成因和解决方法,现分享于此。

延时问题的重要性

主从复制机制广泛应用在udb的内部实现中:udb创建的从库和主库就采用了“主从复制”的数据复制;另外,udb的主打产品“udb mysql高可用实例”,也是采用2个数据库互为主从的“双主模式”来进行数据复制,而双主模式的核心就是主从复制机制。

如果主从复制之间出现延时,就会影响主从数据的一致性。

在高可用复制场景下,我们在udb高可用容灾设计上考虑到,若出现主备数据不一致的场景,默认是不允许进行高可用容灾切换的。因为在主备数据不一致的情况下,此时发生容灾切换,且在新的主库写入了数据,那么从业务角度上,会产生意想不到的严重后果。

复制延时问题,不仅在udb高可用中会带来不良后果,在只读从库的场景下,若从库产生复制延时,也可能会对业务造成一定影响,比如在业务上表现为读写不一致——新增/修改数据查不到等现象。

由此可见,主从复制的延时问题在数据库运营中需要特别关注。一般来说,dba在库上执行'show slave status',并且观察

‘seconds_behind_master'的值,就能够了解当前某个数据库和它的主库之间的数据复制延时。这个值是如此的重要,因此在udb的监控界面上,我们将这个值单独抽取来,设计了“从库同步延时”监控项,以便于运维人员能够直接在控制台上观察。

MySQL数据库主从复制延时超长的解决方法

生产环境中延时问题的分析及解决

我们将最常见的主从复制延时案例总结为几类,以下是相关案例的现象描述、原因分析和解决方法汇总。

◆ 案例一:主库dml请求频繁

某些用户在业务高峰期间,特别是对于数据库主库有大量的写请求操作,即大量insert、delete、update等并发操作的情况下,会出现主从复制延时问题。

现象描述

我们通过观察主库的写操作的qps的值,会看到主库的写操作的qps值突然升高,伴随主从复制延时的上升,可以判断是由于主库dml请求频繁原因造成的。

MySQL数据库主从复制延时超长的解决方法

如上图,可以看出,在17:58分左右qps突增,查看控制台上的写相关qps,也有相应提升。而qps突增的时间,对应的延时也在逐步上升,如下图所示。

MySQL数据库主从复制延时超长的解决方法

原因分析

经过分析,我们认为这是由于主库大量的写请求操作,在短时间产生了大量的binlog。这些操作需要全部同步到从库,并且执行,因此产生了主从的数据复制延时。

从深层次分析原因,是因为在业务高峰期间的主库写入数据是并发写入的,而从库sql thread为单线程回放binlog日志,很容易造成relaylog堆积,产生延时。

解决思路

如果是mysql 5.7以下的版本,可以做分片(sharding),通过水平扩展(scale out)的方法打散写请求,提升写请求写入binlog的并行度。

如果是mysql 5.7以上的版本,在mysql 5.7,使用了基于逻辑时钟(group commit)的并行复制。而在mysql 8.0,使用了基于write set的并行复制。这两种方案都能够提升回放binlog的性能,减少延时。

MySQL数据库主从复制延时超长的解决方法

◆ 案例二:主库执行大事务

大事务指一个事务的执行,耗时非常长。常见产生大事务的语句有:

使用了大量速度很慢的导入数据语句,比如:insert into $tb、select * from $tb、load data infile等;
使用了update、delete语句,对于一个很大的表进行全表的update和delete等。
当这个事务在从库执行回放执行操作时,就有可能会产生主从复制延时。

现象描述

我们从show slave status的结果进行分析,会发现 exec_master_log_pos 字段一直未变,且second_behinds_master持续增加,而 slave_sql_running_state 字段的值为”reading event from the relay log”;同时,分析主库binlog,看主库当前执行的事务,会发现有一些大事务,这样基本可以判定是执行大事务的原因导致的主从复制延时。

MySQL数据库主从复制延时超长的解决方法

原因分析

当大事务记录入binlog并同步到从库之后,从库执行这个事务的操作耗时也非常长,这段时间,就会产生主从复制延时。

举个例子,假如主库花费200s更新了一张大表,在主从库配置相近的情况下,从库也需要花几乎同样的时间更新这张大表,此时从库延时开始堆积,后续的events无法更新。

解决思路

对于这种情况引起的主从复制延时,我们的改进方法是:拆分大事务语句到若干小事务中,这样能够进行及时提交,减小主从复制延时。

◆ 案例三:主库对大表执行ddl语句

ddl全称为 data definition language ,指一些对表结构进行修改操作的语句,比如,对表加一个字段或者加一个索引等等。当ddl对主库大表执行ddl语句的情况下,可能会产生主从复制延时。

现象描述

从现象上,如果从库执行show slave status的输出中,检查exec_master_log_pos一直未动,在排除主库执行大事务的情况下,那么就有可能是在执行大表的 ddl。这一点结合分析主库binlog,看主库当前执行的事务就可以进行确认。

ddl语句的执行情况,可以进一步细分现象来更好地判断:

1.ddl未开始,被阻塞,这时show slave status的结果能检查到slave_sql_running_state为waiting for table metadata lock,且exec_master_log_pos不变;

MySQL数据库主从复制延时超长的解决方法

2.ddl正在执行,sql thread单线程应用导致延时增加。这种情况下观察show slave statu的结果能发现slave_sql_running_state为altering table,而exec_master_log_pos不变。

MySQL数据库主从复制延时超长的解决方法

如果有上述的现象,那么很有可能主库对大表执行ddl语句,同步到从库并在从库回放时,就产生了主从复制延时。

原因分析

ddl导致的主从复制延时的原因和大事务类似,也是因为从库执行ddl的binlog较慢而产生了主从复制延时。

解决思路

遇到这种情况,我们主要通过show processlist或对information_schema.innodb_trx做查询,来找到阻塞ddl语句,并kill掉相关查询,让ddl正常在从库执行。

ddl本身造成的延时难以避免,建议考虑:

避免业务高峰,尽量安排在业务低峰期执行 ;

set sql_log_bin=0后,分别在主从库上手动执行ddl(此操作对于某些ddl操作会造成数据不一致,请务必严格测试),这一条如果用户使用云数据库udb,可以联系ucloud udb运维团队进行协助操作。

◆ 案例四:主库与从库配置不一致

如果主库和从库使用了不同的计算资源和存储资源,或者使用了不同的内核调教参数,可能会造成主从不一致。

现象描述

我们会详细比对主库和从库的性能监控数据,如果发现监控数据差异巨大,结合查看主从的各个配置情况,即可作出明确判断。

原因分析

各种硬件或者资源的配置差异都有可能导致主从的性能差异,从而导致主从复制延时发生:

硬件上:比如,主库实例服务器使用ssd磁盘,而从库实例服务器使用普通sas盘,那么主库产生的写入操作在从库上不能马上消化掉,就产生了主从复制延时;
配置上:比如,raid卡写策略不一致、os内核参数设置不一致、mysql落盘策略不一致等,都是可能的原因。

解决思路

考虑尽量统一db机器的配置(包括硬件及选项参数)。甚至对于某些olap业务,从库实例硬件配置需要略高于主库。

◆ 案例五:表缺乏主键或合适索引

如果数据库的表缺少主键或者合适索引,在主从复制的binlog_format设置为'row'的情况下,可能会产生主从复制延时。

现象描述

我们进行数据库检查时,会发现:

观察show slave status的输出,发现slave_sql_running_state为reading event from the relay log;

show open tables where in_use=1的表一直存在;

观察show slave status的exec_master_log_pos字段不变;

mysqld进程的cpu接近100%(无读业务时),io压力不大。

这些现象出现的情况下,可以认为很可能有表缺乏主键或唯一索引。

原因分析

在主从复制的binlog_format设置为'row'的情况下,比如有这样的一个场景,主库更新一张500万表中的20万行数据。binlog在row格式下,记录到binlog的为20万次update操作,也就是每次操作更新1条记录。如果这条语句恰好有不好的执行计划,如发生全表扫描,那么每一条update语句需要全表扫描。此时sql thread重放将特别慢,造成严重的主从复制延时。

解决思路

这种情况下,我们会去检查表结构,保证每个表都有显式自增主键,并协助用户建立合适索引。

◆ 案例六:从库自身压力过大

有时候,从库性能压力很大的情况下,跟不上主库的更新速度,就产生了主从复制延时。

现象描述

观察数据库实例时,会发现cpu负载过高,io利用率过高等现象,这些导致sql thread应用过慢。这样就可以判断是因为从库自身压力过大引起主从复制延时。

原因分析

部分ucloud用户对于数据库的主从会使用读写分离模式,读请求大部分在从库上执行。在业务有大量读请求的场景下,从库会产生比主库大得多的性能压力。有的用户甚至会在从库运行十分耗费计算资源的olap业务,这也对从库造成了更高的性能挑战,这些都会造成主从复制的延时。

解决思路

这种情况下,我们会建议用户建立更多从库,打散读请求,降低现有从库实例的压力。对于olap业务来说,可以专门建立一个从库来做olap业务,并对这个从库,允许适当的主从复制延时。

总结

在使用mysql的主从复制模式进行数据复制时,主从复制延时是一个需要考量的关键因素。它会影响数据的一致性,进而影响数据库高可用的容灾切换。

在遇到数据库之间出现主从复制延时的情况下,我们团队基于过往经验,归纳出以下方法与流程来协助排查问题:

通过show slave status与show processlist查看现在从库的情况。(顺便也可排除在从库备份时的类似原因);

若exec_master_log_pos不变,考虑大事务、ddl、无主键,检查主库对应的binlog及position即可;

若exec_master_log_pos变化,延时逐步增加,考虑从库机器负载,如io、cpu等,并考虑主库写操作与从库自身压力是否过大。

本文来自:ucloud技术,本文由 ucloud 资深专家丁顺&张苏宁分享。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。