MySQL 主从同步及延迟原因分析

news2024/10/6 14:25:11

主从同步的基本原理

MySQL主从同步步骤详见 MySQL binlog模式及主备的基本原理

主从流程图

谈到主备的并行复制能力,我们要关注的是图中黑色的两个箭头。一个箭头代表了客户端写入主库,另一箭头代表的是从库上sql_thread执行中转日志(relay log

如果用箭头的粗细来代表并行度的话,那么真实情况就如图 1 所示,第一个箭头要明显粗于第二个箭头。

在主库上,影响并发度的原因就是各种锁。 由于 InnoDB 引擎支持行锁,除了所有并发事务都在更新同一行(热点行)这种极端场景外,它对业务并发度的支持还是很友好的。所以,你在性能测试的时候会发现,并发压测32个线程就比单线程时,总体吞吐量高

而日志在备库上的执行,就是图中备库上sql_thread更新数据 (DATA) 的逻辑。如果是用单线程的话,就会导致备库应用日志不够快,造成主备延迟。

主从延迟分析

主从延迟原因分析

正常情况下,在排除网络延迟或丢包的情况下,最直接的影响主从延迟就是从库上sql_thread执行中转日志(relay log),而造成原因一般是以下几种:

1. 从库的机器性能比主库要差

比如将20台主库放在4台机器,把从库放在一台机器。这个时候进行更新操作,由于更新时会触发大量读操作,导致从库机器上的多个从库争夺资源,导致主从延迟。

不过,目前大部分部署都是采取主从使用相同规格的机器部署。

2. 从库的压力大

按照正常的策略,读写分离,主库提供写能力,从库提供读能力。将进行大量查询放在从库上,结果导致从库上耗费了大量的CPU资源,进而影响了同步速度,造成主从延迟。

对于这种情况,可以通过一主多从,分担读压力;也可以采取binlog输出到外部系统,比如Hadoop,让外部系统提供查询能力。

3. 大事务的执行

一旦执行大事务,那么主库必须要等到事务完成之后才会写入binlog。

比如主库执行了一条insert … select非常大的插入操作,该操作产生了近几百G的binlog文件传输到只读节点,进而导致了只读节点出现应用binlog延迟。

因此,DBA经常会提醒开发,不要一次性地试用delete语句删除大量数据,尽可能控制数量,分批进行。

4. 主库的DDL(alter、drop、create)

  1. 只读节点与主库的DDL同步是串行进行,如果DDL操作在主库执行时间很长,那么从库也会消耗同样的时间,比如在主库对一张500W的表添加一个字段耗费了10分钟,那么从节点上也会耗费10分钟。
  2. 从节点上有一个执行时间非常长的的查询正在执行,那么这个查询会堵塞来自主库的DDL,表被锁,直到查询结束为止,进而导致了从节点的数据延迟。

5. 锁冲突

锁冲突问题也可能导致从节点的SQL线程执行慢,比如从机上有一些select … for update的SQL,或者使用了MyISAM引擎等。

6. 从库的复制能力

一般场景中,因偶然情况导致从库延迟了几分钟,都会在从库恢复之后追上主库。但若是从库执行速度低于主库,且主库持续具有压力,就会导致长时间主从延迟,很有可能就是从库复制能力的问题。

从库上的执行,即sql_thread更新逻辑,在5.6版本之前,是只支持单线程,那么在主库并发高、TPS高时,就会出现较大的主从延迟

因此,MySQL自5.7版本后就已经支持并行复制了。可以在从服务上设置slave_parallel_workers为一个大于0的数,然后把slave_parallel_type参数设置为LOGICAL_CLOCK

SHOW VARIABLES LIKE 'slave_parallel%';

主从延迟影响

  1. 查询数据不准确
    为分担主库压力,业务通常会将一些读的请求发送至从库,但如果主从存在延迟的情况,这时读到的可能就是过期的数据。当然,目前在实际业务架构设计中,也会考虑到主从延迟因素的存在,通过如强制走主库、配合半同步(semi-sync)、sleep等方案优化,避免“过期读”对业务造成的影响。

  2. 主库宕机,数据丢失
    主库宕机后,需要较长的恢复时间,但特别是核心业务系统需要快速恢复的紧急情况下,如果之前存在延迟,强制切换主库,保证业务可用,就会导致部分数据丢失,后期的补偿也将会是件很麻烦的事情。

主从延迟处理方案

主从同步问题永远都是一致性和性能的权衡,得看实际的应用场景,若想要减少主从延迟的时间,可以采取下面的办法:

  1. 降低多线程大事务并发的概率,优化业务逻辑
  2. 优化SQL,避免慢SQL,减少批量操作,建议写脚本以update-sleep这样的形式完成
  3. 提高从库机器的配置,减少主库写binlog和从库读binlog的效率差
  4. 尽量采用短的链路,也就是主库和从库服务器的距离尽量要短,提升端口带宽,减少binlog传输的网络延时
  5. 实时性要求的业务读强制走主库,从库只做灾备,备份

并行复制策略

MySQL 5.6 版本前,只支持单线程复制,由此在主库并发高、TPS 高时就会出现严重的主备延迟问题。从单线程复制到最新版本的多线程复制,中间的演化经历了好几个版本

多线程复制机制,都是要把主从流程图中只有一个线程的sql_thread,拆成多个线程

在这里插入图片描述

coordinator就是原来的sql_thread, 不过现在它不再直接更新数据了,只负责读取中转日志和分发事务。真正更新日志的,变成了worker线程。而worker线程的个数,就是由参数slave_parallel_workers决定的

coordinator在分发的时候,需要满足以下这两个基本要求:

  1. 不能造成更新覆盖。这就要求更新同一行的两个事务,必须被分发到同一个worker
  2. 同一个事务不能被拆开,必须放到同一个worker

各个版本的多线程复制,都遵循了这两条基本原则

MySQL 5.5 版本

官方 MySQL 5.5 版本是不支持并行复制的。此段并行策略总结自[MySQL 实战 45 讲]

按表分发策略

按表并行复制程模型

可以看到,每个 worker 线程对应一个 hash 表,用于保存当前正在这个 worker 的“执行队列”里的事务所涉及的表。hash 表的 key 是“库名. 表名”,value 是一个数字,表示队列中有多少个事务修改这个表

事务在分发的时候,跟所有 worker 的冲突关系包括以下三种情况:

  1. 如果跟所有 worker 都不冲突,coordinator 线程就会把这个事务分配给最空闲的 woker
  2. 如果跟多于一个 worker 冲突,coordinator 线程就进入等待状态,直到和这个事务存在冲突关系的 worker 只剩下 1 个
  3. 如果只跟一个 worker 冲突,coordinator 线程就会把这个事务分配给这个存在冲突关系的 worker

这个按表分发的方案,在多个表负载均匀的场景里应用效果很好。但是,如果碰到热点表,比如所有的更新事务都会涉及到某一个表的时候,所有事务都会被分配到同一个 worker 中,就变成单线程复制了

按行分发策略

要解决热点表的并行复制问题,就需要一个按行并行复制的方案。按行复制的核心思路是:如果两个事务没有更新相同的行,它们在备库上可以并行执行。显然,这个模式要求 binlog 格式必须是 row

基于行的策略,事务 hash 表中还需要考虑唯一键,即 key 应该是“库名 + 表名 + 索引 a 的名字 +a 的值”

对比按表分发和按行分发这两个方案的话,按行分发策略的并行度更高。不过,如果是要操作很多行的大事务的话,按行分发的策略有两个问题:

  1. 耗费内存。比如一个语句要删除 100 万行数据,这时候 hash 表就要记录 100 万个项
  2. 耗费 CPU。解析 binlog,然后计算 hash 值,对于大事务,这个成本还是很高的

MySQL 5.6 版本

官方 MySQL5.6 版本,支持了并行复制,只是支持的粒度是按库并行

理解了上面介绍的按表分发策略和按行分发策略,你就理解了,用于决定分发策略的 hash 表里,key 就是数据库名。

这个策略的并行效果,取决于压力模型。如果在主库上有多个 DB,并且各个 DB 的压力均衡,使用这个策略的效果会很好。

相比于按表和按行分发,这个策略有两个优势:

  1. 构造 hash 值的时候很快,只需要库名;而且一个实例上 DB 数也不会很多,不会出现需要构造 100 万个项这种情况。
  2. 不要求 binlog 的格式。因为 statement 格式的 binlog 也可以很容易拿到库名

理论上你可以创建不同的 DB,把相同热度的表均匀分到这些不同的 DB 中,强行使用这个策略。不过由于需要特地移动数据,这个策略应使用得并不多

MySQL 5.7 版本

MySQL5.7 版本也提供了“模拟主库的并行模式”的功能,由参数 slave-parallel-type 来控制并行复制策略:

并行复制策略是通过在主库上将数据分成多个“组”(group)并在从库上并行重放这些组来实现的。每个组包含一组有序的事务,它们可以独立地在从库上重放,而不会与其他组冲突

两阶段提交

只要能够到达 redo log prepare 阶段,就表示事务已经通过锁冲突的检验了,也就表示这些食事务可以并行处理了

MySQL 5.7 并行复制策略的思想是:

  1. 同时处于prepare状态的事务,在备库执行时是可以并行的
  2. 处于prepare状态的事务,与处于commit状态的事务之间,在备库执行时也是可以并行的

在 MySQL 5.7 的并行复制策略里,通过调整参数以拉长binlogwritesync的时间,以此减少binlog的写盘次数,以此来制造更多的“同时处于prepare阶段的事务”。这样就增加了备库复制的并行度

在MySQL 5.7中,可以通过配置参数来控制并行复制的行为。以下是一些与并行复制有关的参数:

参数作用
slave_parallel_workers指定从库上并行执行复制的线程数
slave_parallel_type指定并行复制的类型,可以是LOGICAL_CLOCKDATABASE
log_slave_updates指定是否在主库上记录从库执行的更新操作,以便在从库上进行并行复制
binlog_group_commit_sync_delay指定在主库上等待多长时间来组合多个事务并将它们写入binlog文件
binlog_group_commit_sync_no_delay_count指定在等待时间之前,可以在binlog组合提交中组合的最大事务数

MySQL 5.7.22 版本

MySQL 5.7.22 版本里,MySQL 增加了一个新的并行复制策略,基于WRITESET的并行复制。

相应地,新增了一个参数 binlog-transaction-dependency-tracking,用来控制是否启用这个新策略。这个参数的可选值有以下三种。

  1. COMMIT_ORDER:表示的就是前面介绍的,根据同时进入preparecommit来判断是否可以并行的策略
  2. WRITESET:表示的是对于事务涉及更新的每一行,计算出这一行的 hash 值,组成集合writeset。如果两个事务没有操作相同的行,也就是说它们的writeset没有交集,就可以并行
  3. WRITESET_SESSION:是在WRITESET的基础上多了一个约束,即在主库上同一个线程先后执行的两个事务,在备库执行的时候,要保证相同的先后顺序

对比前面介绍的基于 MySQL 5.5 版本的按行分发的策略是差不多的。不过,MySQL 官方的这个实现还是有很大的优势:

  1. writeset 是在主库生成后直接写入到 binlog 里面的,这样在备库执行的时候,不需要解析 binlog 内容(event 里的行数据),节省了很多计算量
  2. 不需要把整个事务的 binlog 都扫一遍才能决定分发到哪个 worker,更省内存
  3. 由于备库的分发策略不依赖于 binlog 内容,所以 binlog 是 statement 格式也是可以的

对于“表上没主键”和“外键约束”的场景,WRITESET策略也是没法并行的,也会暂时退化为单线程模型


参考资料:

  1. MySQL binlog模式及主备的基本原理
  2. MySQL 实战 45 讲
  3. 加了个字段导致数据库主从延迟,卧槽,疯狂告警
  4. MySQL 常见主从延迟原因分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《Squeeze-and-Excitation Networks》

Squeeze-and-Excitation Networks1. 摘要2. 介绍3. 网络设计4. 代码实现1. 摘要 卷积操作可以使网络通过在每层的局部感受野内融合空间和通道级信息以构建信息特征;空间信息尝试通过加强CNN整个特征层次的空间编码质量以加强CNN的表示能力;本文主要聚焦…

【计算机网络-应用层】万维网

文章目录1 统一资源定位符 URL2 万维网文档2.1 超文本标记语言 HTML2.2 层叠样式表 CSS2.3 JavaScript3 超文本传输协议 HTTP3.1 HTTP 报文格式3.1.1 HTTP 请求报文3.1.2 HTTP 响应报文3.2 HTTP 的工作过程3.2.1 HTTP/1.03.2.2 HTTP/1.13.2.3 相关例题4 Cookie1 统一资源定位符…

如何从根本上防止服务器被攻击

随着互联网的发展,服务器成为了企业和个人网络应用的重要基础设施。但是,随之而来的网络安全威胁也在不断增加,服务器安全问题也成为了影响企业信息安全的重要因素。针对这种情况,服务器安全防御变得尤为重要。   服务器安全防御…

6.Swagger的实战使用

六.Swagger的实战使用 1.什么是swagger 2.swagger的基本使用 3.swagger实战使用 六.Swagger的实战使用 1.什么是swagger swagger是后端接口文档的生成并且提供ui界面进行测试过去用postman测试 缺点:需要自己写地址,如果项目变了需要自己更改 2.sw…

CF区间DP作业题解

1. Recovering BST 由于互质关系不是传递的,所以尽量挂在树的最下面,刚好构成二叉树 f[i][j][0]f[i][j][0]f[i][j][0] 表示区间 [i,j][i,j][i,j] 以 iii 为根,是否可以构成一棵树。 f[i][j][1]f[i][j][1]f[i][j][1] 表示区间 [i,j][i,j][i,j…

Spring理论学习

1、什么是IOC IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。不过, IoC 并非 Spring 特有,…

阿里通义千问、ChatGPT和文心一言有何区别,在哪里能使用?

目前,聊天机器人技术在人工智能领域的发展越来越成熟了。现在已经有几款备受关注的聊天机器人产品问世,例如ChatGPT、阿里的通义千问和百度的文心一言。它们有什么区别,怎么使用呢? 其实,我也挺好奇的,毕竟…

人人拥有ChatGPT的时代来临了,这次微软很大方!

技术迭代的在一段时间内是均匀发展甚至止步不前的,但在某段时间内会指数级别的爆发。 ChatGPT背后的GPT 3.5训练据说花了几百万美金外加几个月的时间,参数大概有1700多亿。 这对于绝大多数的个人或企业来说绝对是太过昂贵的。 然而,微软&am…

月薪过 3w 的 软件测试工程师 都是怎么做到的?

对任何职业而言,薪资始终都会是众多追求的重要部分。前几年的软件测试行业还是一个风口,随着不断地转行人员以及毕业的大学生疯狂地涌入软件测试行业,目前软件测试行业“缺口”已经基本饱和。 当然,我说的是最基础的功能测试的岗…

如何使用双轴XY平台绘制正弦曲线

1. 功能说明 本文示例将实现双轴XY平台绘制正弦曲线的功能。 2. 电子硬件 在这个示例中,采用了以下硬件,请大家参考: 主控板 Basra主控板(兼容Arduino Uno) 扩展板 Bigfish2.1扩展板 SH-ST步进电机扩展板 电池11.1V动…

跟着原子学I2C

I2C通讯 1、IIC总线介绍 集成电路总线,是一种同步串行半双工通信总线。 总线or协议?! 总线是数据传输通道,协议是数据传输规则。 1、1介绍 a、由时钟线SCL和数据线SDA组成,并且都接上拉电阻,确保总线空…

UDP套接字

大家好,又见面了,🎉🎉🎉🌸🌸🌸 今天为大家带来UDP套接字的相关知识 文章目录认识socketUDP和TCP认识UDPAPI有关方法基于UDP实现回显服务器UDP的方法基于UDP实现回显程序认识socket UDP和TCP 认识UDPAPI有…

【数据结构】二叉树的概念及结构

🚀write in front🚀 📜所属专栏: 初阶数据结构 🛰️博客主页:睿睿的博客主页 🛰️代码仓库:🎉VS2022_C语言仓库 🎡您的点赞、关注、收藏、评论,是…

Linux内核设备驱动设备树概念与使用

一、设备树概念以及作用 1.1设备树概念 设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(DeviceTree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比…

prometheus基本介绍

001 基本介绍 1.主要功能 多维数据模型(时序由metric名字和k/v的labels构成)灵活的查询语句无依赖存储,支持local和remote不同的模型采用http协议,使用pull模式,拉取数据,简单易懂监控目标,可…

session,zookeeper,mq-rabbitmq,kafka,websocket

spring-boot-demo-session pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://…

INSERT INTO IF NOT EXISTS问题

情景说明&#xff1a;工作上遇到一个树形结构的数据&#xff0c;如有文件夹和子文件夹这样的数据。由于后端逻辑问题&#xff0c;导致在前端页面操作了删除功能后&#xff0c;数据库中仅部分数据被删除&#xff0c;比如只把根节点或是父节点删除了&#xff0c;没有级联删除所有…

九龙证券|什么是庄家洗盘和出货?各有什么特征?

在股市独占的是庄家&#xff0c;在市场上独占的是商人。庄家的存在便是为了把资金投入市场变成本钱&#xff0c;使用本钱获取最大赢利。庄家的各类方法也是为了不惜一切代价获取最大赢利。今天我们来了解什么是庄家洗盘和出货&#xff1f;各有什么特征&#xff1f;下面就为大家…

所有知识付费都可以用 ChatGPT 再割一次?

伴随春天一起到来的&#xff0c;还有如雨后春笋般冒出的 ChatGPT / AI 相关的付费社群、课程训练营、知识星球等。 ChatGPT 吹来的这股 AI 热潮&#xff0c;这几个月想必大家多多少少都能感受到。 ▲ 图片来源&#xff1a;网络 这两张图是最近在圈子里看到的。 一张是国内各…

SpringBoot —— 日志基本操作

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ SpringBoot —— 日志基本操作一、日志的作用二…