热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql主从复制延迟原因_主从复制延迟原因剖析!

写在前面:之前在维护线上主从复制架构的时候,遇到了一些主从延迟问题,笔者呢,也是比较好学的,哈哈!

写在前面:

之前在维护线上主从复制架构的时候,遇到了一些主从延迟问题,笔者呢,也是比较好学的,哈哈!所以,查阅了诸多资料,然后去其糟粕,根据自己的理解和查阅的资料整理成了本文,在此申明,本文内容是笔者自己的理解,不代表权威性,仅供各位同行做个参考,自己呢,也做个学习记录。本着实事求是的原则,对于网上的诸多资料,笔者自己也只是信5分,怀疑5分,就算是官方的资料,有的也有bug不是,只有自己动手实践过了,才能相信,才有发言权,其他的,一切都是虚的!

MySQL主从复制过程:

1)主库 Binlog Dump线程在binlog有变化时,主动发送最新的binlog到从库。

2)从库 I/O线程被动接收主库传来的binlog之后,记录到从库的relay log中,当没有数据传入的时候则会等待。与此同时SQL线程重放 relay log。

3)当从库长时间未收到主库传来的数据,并且等待时间超过了slave_net_timeout定义的时间(默认3600秒)后,Slave_IO_State的状态将会置为No。在此之后,每隔MASTER_CONNECT_RETRY [Connect_Retry: 30]定义的时间(默认60秒)将会尝试重新连接,直到连接成功或超过重试次数MASTER_RETRY_COUNT [Master_Retry_Count: 6666](默认86400次)。

slave_net_timeout可以在配置文件中修改或set variable在线设置

而 MASTER_CONNECT_RETRY、MASTER_RETRY_COUNT 需要在CHANGE MASTER TO建立复制关系时提前指定

在线变更 slave_net_timeout:

SHOW VARIABLES LIKE 'slave_net_timeout'

Variable_name          `Value`

slave_net_timeout      3600

SET GLOBAL slave_net_timeout=1800

修改MASTER_CONNECT_RETRY=30,MASTER_RETRY_COUNT值:

mysql> change master to MASTER_CONNECT_RETRY=30,MASTER_RETRY_COUNT=6666;

ERROR 1198 (HY000): This operation cannot be performed with a running slave; run STOP SLAVE first

mysql> stop slave;

Query OK, 0 rows affected (0.01 sec)

mysql> change master to MASTER_CONNECT_RETRY=30,MASTER_RETRY_COUNT=6666;

Query OK, 0 rows affected (0.01 sec)

mysql> start slave;

Query OK, 0 rows affected (0.02 sec)

MySQL主从复制延迟是怎样形成的:

1、主库的worker线程在写binlog的时候是并发工作的(并行写入),而主库的dump线程和从库的IO线程都是单线程推拉binlog,特别是SQL线程是拿着relay log中的event逐一单线程回放的(5.6版本开启slave_parallel_workers支持特定情况下的并行复制,5.7版本之后全面支持并行复制后在复制层面已极大改善了延迟问题)。因此即使不考虑网络延迟,主流MySQL版本在高并发的情况下,消费很可能赶不上生产,采用异步复制的从库很有可能跟不上主库的进度。

2、在复制期间,无论是主库或从库负载高(特别是从库落盘压力大,关系到sync_binlog、innodb_flush_log_at_trx_commit的设置)或者是网络传输慢(特别是跨机房的同步)等情况发生时,都会产生主从延迟,并且是不可避免的。如果要实现强一致性,可采用Semi-sync,但采用该plugin也无法保证持续强一致性(rpl_semi_sync_master_timeout会引起复制模式的降级)

根据MySQL主从复制延迟的形成原因,以下情况可能导致MySQL主从复制延迟:

1)MASTER高并发,形成大量事务

2)网络状况差

3)从库的硬件配置没有主库的好

4)本来就是异步复制

关于落盘时的部分参数解释:

sync_binlog:

解释:

Controlshow oftenthe MySQL server synchronizes the binary log to disk

控制MySQL将二进制日志(binary log)同步到磁盘的频率

sync_binlog=0:

Disables synchronization of the binary log to disk by the MySQL server. Instead, the MySQL server relies on the operating system to flush the binary log to disk from time to time as it does for any other file. This setting provides the best performance, but in the event of a power failure or operating system crash, it is possible that the server has committed transactions that have not been synchronized to the binary log.

sync_binlog=1:

Enables synchronization of the binary log to disk before transactions are committed. This is the safest setting but can have a negative impact on performance due to the increased number of disk writes. In the event of a power failure or operating system crash, transactions that are missing from the binary log are only in a prepared state. This permits the automatic recovery routine to roll back the transactions, which guarantees that no transaction is lost from the binary log.

sync_binlog=N:

where N is a value other than 0 or 1: The binary log is synchronized to disk after N binary log commit groups have been collected. In the event of a power failure or operating system crash, it is possible that the server has committed transactions that have not been flushed to the binary log. This setting can have a negative impact on performance due to the increased number of disk writes. A higher value improves performance, but with an increased risk of data loss.

innodb_flush_log_at_trx_commit:

其他参考文档:

解释:

是 InnoDB 引擎特有的,ib_logfile的刷新方式

MySQL日志写入顺序:

log buffer => MySQL(write) => log file => OS刷新(flush) => disk

innodb_flush_log_at_trx_commit取值解释:(从一些博客之中参考的)

0,延迟写:

log buffer => 每隔1秒 => log file => OS 实时flush => disk

1,实时写,实时刷:

log buffer => 实时 => log file => OS实时flush => disk

这样的话,数据库对IO的要求就非常高了,如果底层的硬件提供的IOPS比较差,那么MySQL数据库的并发很快就会由于硬件IO的问题而无法提升

2,实时写,延迟刷:

log buffer => 实时 => log file => OS每隔1秒 => disk

如果只是MySQL数据库挂掉了,由于文件系统没有问题,那么对应的事务数据并没有丢失。只有在数据库所在的主机操作系统损坏或者突然掉电的情况下,数据库的事务数据可能丢失1秒之类的事务数据。这样的好处,减少了事务数据丢失的概率,而对底层硬件的IO要求也没有那么高(log buffer写到文件系统中,一般只是从log buffer的内存转移的文件系统的内存缓存中,对底层IO没有压力)。

官方文档中文解释:(笔者自己的理解)

当innodb_flush_log_at_trx_commit,被设置为0,日志缓冲(log buffer)每秒一次地被写入到日志文件(log file),并且对日志文件做磁盘刷新(flush disk),该模式下在事务提交的时候,不会主动触发写入磁盘的操作。

当innodb_flush_log_at_trx_commit,被设置为1,在每个事务提交时,日志缓冲(log buffer)被写入到日志文件(log file),并且对日志文件做磁盘刷新(flush disk) [同时进行]

当innodb_flush_log_at_trx_commit,被设置为2,在每个事务提交时,日志缓冲(log buffer)被写入到日志文件(log file),但不对日志文件做磁盘刷新(flush disk) [不同时进行],该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作

因为进程安排问题,每秒一次的刷新不是100%保证都会发生。可以通过设置innodb_flush_log_at_trx_commit值不为1来获得较好的性能,但如果你设置此值为0,那么MySQL崩溃会丢失崩溃前1秒的事务(该模式下性能最好,但不×××全);如果设置此值为2,当操作系统崩溃或断电时才会丢失最后1秒的事务(该模式下性能较好,也比0模式安全)。如果设置此值为0,该模式性能最低,但是最安全的模式。在MySQL服务崩溃或者操作系统crash的情况下,binlog只会丢失一个语句或一个事务。

注意,许多操作系统和一些磁盘硬件会欺骗刷新到磁盘操作(flush disk)。尽管刷新没有进行,也会告诉MySQL刷新已经进行。即使设置此值为1,事务的持久性也不被保证,且在最坏的情况下断电甚至会破坏数据库。在SCSI磁盘控制器中,或在磁盘自身中,使用有后备电池的磁盘缓存会加速文件刷新并且使得操作更安全。可以试着使用hdparm命令在硬件缓存中禁止磁盘写缓存,或者使用其他一些对硬件提供商专用的命令

最后MySQL官方建议:

A higher value improves performance, but with an increased risk of data loss

For the greatest possible durability and consistency in a replication setup that uses InnoDB with transactions, use these settings:

sync_binlog=1

innodb_flush_log_at_trx_commit=1

MySQL主从延迟如何计算:

第一种计算方式:position(简单粗暴,仅仅能看出是否有延迟)

mysql> show slave status\G;

Read_Master_Log_Pos: 4

Exec_Master_Log_Pos: 0

第二种计算方式:Seconds_Behind_Master

参考MySQL官方文档:

参考其他文章:

1) 当SQL线程执行event时,从库执行时刻的timestamp值 减去 该event上附带的时间戳(当时主库上的timestamp),这两者的差值

2) 一旦SQL线程未在执行event,则Seconds_Behind_Master为0

3) IO线程或SQL线程 is not running,则Seconds_Behind_Master为NULL

4) Seconds_Behind_Master为0时,表示master slave 复制没有延迟(绝大情况下如此)

在网络很快的情况下,io thread 很快的从master获取binlog到slave的realy log,然后sql thread replay,此时Seconds_Behind_Master值能真正表示slave落后于master的秒数。

在网络很差的情况下,io thread同步master的binlog很慢,而sql thread replay很快,此时Seconds_Behind_Master也是0,但真正情况是,slave落后于master很多

假如有以下3种情况发生,虽然Seconds_Behind_Master仍然存在非NULL的值,但已经变得不准确

1、主从时间不一致(虽然引入了clock_diff_with_master,尽量调节时间差带来的影响,但该值仅在从库与主库建立连接之时获取,后续不再更新,若之后再去修改主从机的时间,该值就不可靠了)。

2、主从库间网络问题或者从库IO线程未发现主库的binlog dump 线程挂了,仍然在等待数据传输过来,SBM长时间持续为零。

3、主库有较大的binlog event执行前后,从库上看到的SBM将会有大的跳动(监控图中将很可能产生毛刺)

4、对于并行复制,SMB是基于Exec_Master_Log_Pos,不精准。



推荐阅读
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 本文详细介绍了MySQL数据库服务器(mysqld)和客户端(mysql)的区别,并提供了多种启动和关闭MySQL服务器的方法。通过这些方法,您可以更好地管理和维护MySQL数据库。 ... [详细]
  • 本文详细介绍了如何在Linux系统(以CentOS为例)上彻底卸载Zimbra邮件系统,包括停止服务、删除文件和用户等步骤。 ... [详细]
  • 用阿里云的免费 SSL 证书让网站从 HTTP 换成 HTTPS
    HTTP协议是不加密传输数据的,也就是用户跟你的网站之间传递数据有可能在途中被截获,破解传递的真实内容,所以使用不加密的HTTP的网站是不 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • Juval Löwy主张,每个类都应被视为服务,这并非是为了让服务无处不在,而是因为微服务是经过深思熟虑后系统分解的自然结果。在他的设计和构建的系统中,这种理念有助于提高模块化、可维护性和扩展性。通过将每个类视为独立的服务,系统能够更好地应对复杂性,实现更灵活的部署和更高的性能。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • Python错误重试让多少开发者头疼?高效解决方案出炉
    ### 优化后的摘要在处理 Python 开发中的错误重试问题时,许多开发者常常感到困扰。为了应对这一挑战,`tenacity` 库提供了一种高效的解决方案。首先,通过 `pip install tenacity` 安装该库。使用时,可以通过简单的规则配置重试策略。例如,可以设置多个重试条件,使用 `|`(或)和 `&`(与)操作符组合不同的参数,从而实现灵活的错误重试机制。此外,`tenacity` 还支持自定义等待时间、重试次数和异常处理,为开发者提供了强大的工具来提高代码的健壮性和可靠性。 ... [详细]
  • 本文深入探讨了如何选择适合业务需求的MySQL存储引擎,详细解析了不同存储引擎的特点、适用场景及其在数据存储和管理中的优势。通过对比InnoDB、MyISAM等主流引擎,为读者提供了全面的技术指导和专业建议,帮助开发者在实际应用中做出明智的选择。 ... [详细]
  • 深入解析 OpenSSL 生成 SM2 证书:非对称加密技术与数字证书、数字签名的关联分析
    本文深入探讨了 OpenSSL 在生成 SM2 证书过程中的技术细节,重点分析了非对称加密技术在数字证书和数字签名中的应用。非对称加密通过使用公钥和私钥对数据进行加解密,确保了信息传输的安全性。公钥可以公开分发,用于加密数据或验证签名,而私钥则需严格保密,用于解密数据或生成签名。文章详细介绍了 OpenSSL 如何利用这些原理生成 SM2 证书,并讨论了其在实际应用中的安全性和有效性。 ... [详细]
  • Cosmos生态系统为何迅速崛起,波卡作为跨链巨头应如何应对挑战?
    Cosmos生态系统为何迅速崛起,波卡作为跨链巨头应如何应对挑战? ... [详细]
author-avatar
想零的时候
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有