从库延迟案例分析

news2024/11/25 10:26:08

背景介绍

近来一套业务系统,从库一直处于延迟状态,无法追上主库,导致业务风险较大。从资源上看,从库的CPU、IO、网络使用率较低,不存在服务器压力过高导致回放慢的情况;从库开启了并行回放;在从库上执行show processlist看到没有回放线程阻塞,回放一直在持续;解析relay-log日志文件,发现其中并没大事务回放。

过程分析

现象确认

收到运维同事的反馈,有一套从库延迟的非常厉害,提供了show slave status延迟的截图信息

file

持续观察了一阵show slave status的变化,发现pos点位信息在不停的变化,Seconds_Behind_master也是不停的变化的,总体趋势还在不停的变大。

资源使用

观察了服务器资源使用情况,可以看到占用非常低

file

观察从库进程情况,基本上只能看到有一个线程在回放工作

file

并行回放参数说明

在主库设置了binlog_transaction_dependency_tracking=WRITESET

在从库设置了slave_parallel_type=LOGICAL_CLOCKslave_parallel_workers=64

error log日志对比

从error log中取并行回放的日志进行分析

$ grep 010559 100werror3306.log | tail -n 3
2024-01-31T14:07:50.172007+08:00 6806 [Note] [MY-010559] [Repl] Multi-threaded slave statistics for channel 'cluster': seconds elapsed = 120; events assigned = 3318582273; worker queues filled over overrun level = 207029; waite
d due a Worker queue full = 238; waited due the total size = 0; waited at clock conflicts = 348754579743300 waited (count) when Workers occupied = 34529247 waited when Workers occupied = 76847369713200

2024-01-31T14:09:50.078829+08:00 6806 [Note] [MY-010559] [Repl] Multi-threaded slave statistics for channel 'cluster': seconds elapsed = 120; events assigned = 3319256065; worker queues filled over overrun level = 207029; waite
d due a Worker queue full = 238; waited due the total size = 0; waited at clock conflicts = 348851330164000 waited (count) when Workers occupied = 34535857 waited when Workers occupied = 76866419841900

2024-01-31T14:11:50.060510+08:00 6806 [Note] [MY-010559] [Repl] Multi-threaded slave statistics for channel 'cluster': seconds elapsed = 120; events assigned = 3319894017; worker queues filled over overrun level = 207029; waite
d due a Worker queue full = 238; waited due the total size = 0; waited at clock conflicts = 348943740455400 waited (count) when Workers occupied = 34542790 waited when Workers occupied = 76890229805500

上述信息的详细解释,可以参考MTS性能监控你知道多少

去掉了发生次数比较少的统计,显示了一些关键数据的对比

file

可以发现自然时间120,回放的协调线程有90多秒由于无法并行回放而进入等待,有近20秒是由于没有空闲的work线程进入等待,折算下来协调线程工作的时间只有10秒左右。

并行度统计

众所周知,mysql从库并行回放主要依赖于binlog中的last_commmitted来做判断,如果事务的last_committed相同,则基本上可以认为这些事务可以并行回放,下面从环境中获取一个relay log进行并行回放的大概统计

$ mysqlsqlbinlog --no-defaults 046638 |grep -o 'last_committed.*' | sed 's/=/ /g' | awk '{print $2}' |sort -n | uniq -c |awk 'BEGIN {print "last_commited group_count Percentage"} {count[$2]=$1
; sum+=$1} END {for (i in count) printf "%d %d %.2f%%\n", i, count[i], (count[i]/sum)*100|"sort -k 1,1n"}' | awk '{if($2>=1 && $2 <11){sum+=$2}} END {print sum}' 
235703
$ mysqlsqlbinlog --no-defaults 046638 |grep -o 'last_committed.*' | sed 's/=/ /g' | awk '{print $2}' |sort -n | uniq -c |awk 'BEGIN {print "last_commited group_count Percentage"} {count[$2]=$1
; sum+=$1} END {for (i in count) printf "%d %d %.2f%%\n", i, count[i], (count[i]/sum)*100|"sort -k 1,1n"}' | awk '{if($2>10){sum+=$2}} END {print sum}'
314694

上述第一条命令,是统计last_committed相同的事务数量在1-10个,即并行回放程度较低或者是无法并行回放,这些事务总数量为235703,占43%,详细解析并行回放度比较低的事务分布,可以看出这部分last_committed基本上都是单条的,都需要等待先序事务回放完成后,自己才能进行回放,这就会造成前面日志中观察到的协调线程等待无法并行回放而进入等待的时间比较长的情况

$ mysqlbinlog --no-defaults 046638 |grep -o 'last_committed.*' | sed 's/=/ /g' | awk '{print $2}' |sort -n | uniq -c |awk 'BEGIN {print "last_commited group_count Percentage"} {count[$2]=$1; sum+=$1} END {for (i in count) printf "%d %d %.2f%%\n", i, count[i], (count[i]/sum)*100|"sort -k 1,1n"}' | awk '{if($2>=1 && $2 <11) {print $2}}' | sort | uniq -c
 200863 1
  17236 2
     98 3
     13 4
      3 5
      1 7

第二条命令统计last_committed相同的事务数量超过10个的总事务数,其数量为314694,占57%,详细解析了这些并行回放度比较高的事务,可以看到每一组是在6500~9000个事务数间

$ mysqlsqlbinlog --no-defaults 046638 |grep -o 'last_committed.*' | sed 's/=/ /g' | awk '{print $2}' |sort -n | uniq -c |awk 'BEGIN {print "last_commited group_count Percentage"} {count[$2]=$1
; sum+=$1} END {for (i in count) printf "%d %d %.2f%%\n", i, count[i], (count[i]/sum)*100|"sort -k 1,1n"}' | awk '{if($2>11){print $0}}' | column -t
last_commited  group_count  Percentage
1              7340         1.33%
11938          7226         1.31%
23558          7249         1.32%
35248          6848         1.24%
46421          7720         1.40%
59128          7481         1.36%
70789          7598         1.38%
82474          6538         1.19%
93366          6988         1.27%
104628         7968         1.45%
116890         7190         1.31%
128034         6750         1.23%
138849         7513         1.37%
150522         6966         1.27%
161989         7972         1.45%
175599         8315         1.51%
189320         8235         1.50%
202845         8415         1.53%
218077         8690         1.58%
234248         8623         1.57%
249647         8551         1.55%
264860         8958         1.63%
280962         8900         1.62%
297724         8768         1.59%
313092         8620         1.57%
327972         9179         1.67%
344435         8416         1.53%
359580         8924         1.62%
375314         8160         1.48%
390564         9333         1.70%
407106         8637         1.57%
422777         8493         1.54%
438500         8046         1.46%
453607         8948         1.63%
470939         8553         1.55%
486706         8339         1.52%
503562         8385         1.52%
520179         8313         1.51%
535929         7546         1.37%

last_committed机制介绍

主库的参数binlog_transaction_dependency_tracking用于指定如何生成其写入二进制日志的依赖信息,以帮助从库确定哪些事务可以并行执行,即通过该参数控制last_committed的生成机制,参数可选值有COMMIT_ORDER、WRITESET、SESSION_WRITESET。 从下面这段代码,很容易看出来三种参数关系:

1) 基础算法为COMMIT_ORDER 2) WRITESET算法是在COMMIT_ORDER基础上再计算一次 3) SESSION_WRITESET算法是在WRITESET基础上再计算一次

file

由于我的实例设置的是WRITESET,因此关注COMMIT_ORDER算法和的WRITESET算法即可。

COMMIT_ORDER

COMMIT_ORDER计算规则:如果两个事务在主节点上是同时提交的,说明两个事务的数据之间没有冲突,那么一定也是可以在从节点上并行执行的,理想中的典型案例如下面的例子

session-1session-2
BEGINBEGIN
INSERT t1 values(1)
INSERT t2 values(2)
commit (group_commit)commit (group_commit)

但对于MySQL来说,group_commit是内部行为,只要session-1和session-2是同时执行commit,不管内部是否合并为group_commit,两个事务的数据本质上都是没有冲突的;再退一步来讲,只要session-1执行commit之后,session-2没有新的数据写入,两个事务依旧没有数据冲突,依然可以并行复制。

session-1session-2
BEGINBEGIN
INSERT t1 values(1)
INSERT t2 values(2)
commit
commit

对于更多并发线程的场景,可能这些线程不能同时并行复制,但部分事务却可以。以如下一个执行顺序来说,在session-3提交之后,session-2没有新的写入,那么这两个事务是可以并行复制的;而session-3提交后,session-1又插入了一条新的数据,此时无法判定数据冲突,所以session-3和session-1的事务无法并行复制;但session-2提交后,session-1之后没有新数据写入,所以session-2和session-1又可以并行复制。因此,这个场景中,session-2分别可以和session-1,session-3并行复制,但3个事务无法同时并行复制。

session-1session-2session-3
BEGINBEGINBEGIN
INSERT t1 values(1)INSERT t2 values(1)INSERT t3 values(1)
INSERT t1 values(2)INSERT t2 values(2)
commit
INSERT t1 values(3)
commit
commit
WRITESET

实际上是commit_order+writeset的组合,会先通过commit_order计算出一个last_committed值,然后再通过writeset计算一个新值,最后取两者间的小值作为最终事务gtid的last_committed。

在MySQL中,writeset本质上是对 schema_name + table_name + primary_key/unique_key 计算的hash值,在DML执行语句过程中,通过binlog_log_row生成row_event之前,会将DML语句中所有的主键/唯一键都单独计算hash值,并加入到事务本身的writeset列表中。而如果存在无主键/唯一索引的表,还会对事务设置has_missing_keys=true。

参数设置为WRITESET,但是并不一定就能使用上,其限制如下

1) 非DDL语句或者表具有主键或者唯一键或者空事务 2) 当前session使用的hash算法与hash map中的一致 3) 未使用外键 4) hash map的容量未超过binlog_transaction_dependency_history_size的设置 以上4个条件均满足时,则可以使用WRITESET算法,如果有任意一个条件不满足,则会退化为COMMIT_ORDER计算方式

file

具体WRITESET算法如下,事务提交时:

  1. last_committed设置为m_writeset_history_start,此值为m_writeset_history列表中最小的sequence_number

  2. 遍历事务的writeset列表

    a 如果某个writeset在全局m_writeset_history中不存在,构建一个pair<writeset, 当前事务的sequence_number>对象,插入到全局m_writeset_history列表中

    b. 如果存在,那么last_committed=max(last_committed, 历史writeset的sequence_number值),并同时更新m_writeset_history中该writeset对应的sequence_number为当前事务值

  3. 如果has_missing_keys=false,即事务所有数据表均包含主键或者唯一索引,则最后取commit_order和writeset两种方式计算的最小值作为最终的last_committed值

file

TIPS:基于上面WRITESET规则,就会出现后提交的事务的last_committed比先提交的事务还小的情况

结论分析

结论描述

根据WRITESET的使用限制,对relay-log及事务中涉及到的表结构进行了对比,分析单last_committed的事务组成发现如下两种情况:

1) 单last_committed的事务中涉及到的数据和sequence_number存在数据冲突 2) 单last_committed的事务中涉及到的表存在无主键的情况,而且这种事务特别多

从上面的分析中可以得出结论:无主键表的事务太多,导致WRITESET退化为COMMIT_ORDER,而由于数据库为TP应用,事务都快速提交,多个事务提交无法保证在一个commit周期内,导致COMMIT_ORDER机制产生的last_committed重复读很低。从库也就只能串行回放这些事务,引起回放延迟。

优化措施

1) 从业务侧对表做改造,在允许的情况下给相关表都添加上主键。 2) 尝试调大参数binlog_group_commit_sync_delay、binlog_group_commit_sync_no_delay_count从0修改为10000,由于特殊环境限制,该调整并未生效,不同的场景可能会有不同的表现。


Enjoy GreatSQL :)

关于 GreatSQL

GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

image

社区有奖建议反馈: https://greatsql.cn/thread-54-1-1.html

社区博客有奖征稿详情: https://greatsql.cn/thread-100-1-1.html

(对文章有疑问或者有独到见解都可以去社区官网提出或分享哦~)

技术交流群:

微信&QQ群:

QQ群:533341697

微信群:添加GreatSQL社区助手(微信号:wanlidbc )好友,待社区助手拉您进群。

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

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

相关文章

一键提升Edge浏览器生产力

Edge作为微软的产品&#xff0c;其具体使用和特性在此不再赘述&#xff0c;其中对我个人而言较有吸引力的部分是其扩展部分。正是有了其丰富的扩展插件&#xff0c;其生产力才能一键跃升&#xff0c;今天让我们一起来探索几款有用&#xff08;有趣&#xff09;的扩展插件。 1.…

NASA数据集—— 亚洲夏季季风化学和气候影响项目(ACCLIP)Roscoe 激光雷达收集的云和气溶胶ADO遥感数据

ACCLIP WB-57 Aerosol and Cloud Remotely Sensed Data 简介 ACCLIP_AerosolCloud_AircraftRemoteSensing_WB57_Data 是亚洲夏季季风化学和气候影响项目&#xff08;ACCLIP&#xff09;期间从 Roscoe 激光雷达收集的云和气溶胶遥感数据。该产品的数据收集工作已经完成。 亚洲…

【汇编】_Visual Studio2019写32位汇编

目录 第一步&#xff1a;创建新项目 1. 空项目—下一步 2. 选择位置—填写项目名—创建 第二步&#xff1a;项目生成依赖项 1. 右击项目名—生成依赖项—生成自定义 2. 选中masm—确定 第三步&#xff1a;创建源文件 1. 源文件—添加—新建项 2. 选择C文件—创建新文件…

ActiveMQ + MQTT 集群搭建(虚机版本) + Springboot使用配置

文章目录 前言一、ActiveMQ、 MQTT是什么&#xff1f;1.ActiveMQ介绍2.MQTT介绍 二、集群搭建步骤1.下载apache-activemq-5.15.12-bin.tar.gz2.上传apache-activemq-5.15.12-bin.tar.gz到服务器并解压文件到文件夹clusters、master、slave三个文件夹下面形成三个节点&#xff0…

配置QtCreator能加载自定义插件的环境

配置对应环境 引言查看当前版本配置能够加载插件的环境 引言 生成的自定义插件能在QtCreator的设计器中加载&#xff0c;需要满足当前使用的QtCreator的编译时所需的Qt库和编译器。 查看当前版本 这里需要先查看自己使用的QtCreator的版本&#xff0c;即生成QtCreator时使用…

17(18)-1-HTML5 新增语义标签及属性

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍HTML5 新增语义标签及属性&#x1f48e;1 HTML5 新增的块级语义化标签&…

C语言——指针的高级引用

目录 1.概述 2.虚拟内存空间 2.1存储期限 2.2栈区管理 2.3堆区域的使用 3.动态内存分配和释放&#xff08;重点&#xff09; 3.1通用指针类型void 3.2内存分配malloc函数 3.2.1 malloc函数&#xff08;memory allocation&#xff09;&#xff08;注意len*size&#xff…

SAP SD学习笔记04 - 出荷Plant(交货工厂),出荷Point(装运点),输送计划,品目的可用性检查,一括纳入/分割纳入,仓库管理

上一章讲了SD的主数据。 SAP SD学习笔记03 - SD模块中的主数据-CSDN博客 本章讲出荷Plant&#xff08;交货工厂&#xff09;&#xff0c;出荷Point&#xff08;装运点&#xff09;和出和路线。 还是偏理论多一些&#xff0c;后面的文章尽量多加些练习巩固一下。 1&#xff0…

Element-UI plus 自定义-下拉框选择年份【vue3】

1.实现效果 2.实现代码展示 <template><el-select v-model"selectedYear" placeholder"请选择"><el-optionv-for"year in yearOptions":key"year":label"year":value"year"></el-option>…

实验四:基于内容的推荐

代码 import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity from sklearn.metrics.pairwise import pairwise_distances import numpy as np news_dfpd.read_csv(C:/Users/Administrat…

【Linux】开始了解重定向

送给大家一句话&#xff1a; 人真正的名字是&#xff1a;欲望。所以你得知道&#xff0c;消灭恐惧最有效的办法&#xff0c;就是消灭欲望。 – 史铁生 《我与地坛》 开始了解重定向 1 前言2 重定向与缓冲区2.1 文件描述符分配规则2.2 重定向的现象2.3 重定向的理解2.4 缓冲区…

阿里云微调chatglm3-6b---只有一个python解释器但gradio要求版本不兼容怎么办

安装LLAMA参考博文http://t.csdnimg.cn/6yYwG 在用LLAMA微调大模型的时候总是出现connected error out并且出现这样的界面 这是由于LLMA所要求的gradio版本>4.0.0,<4.2.0&#xff0c;然而chatglm3-6b要求的gradio版本需要gradio3.39.0才能显示出web_demo_gradio.py渲染…

10.1K star !牛逼了!开源技术速查表,推荐人手一份!

1、前言 在当今信息爆炸的时代&#xff0c;知识的获取、整理和应用显得尤为重要。随着个人职业发展和学习需求的不断提升&#xff0c;搭建一个个人知识库已成为提升竞争力的关键一环。个人知识库不仅是一个信息的存储库&#xff0c;更是一个思维的工具箱&#xff0c;它能够帮助…

【前缀积】Leetcode 除自身以外数组的乘积

题目解析 238. 除自身以外数组的乘积 算法讲解 我们可以使用两个空间保存当前位置的左边积和右边积&#xff0c;需要注意的地方初始的dp表需要初始化为1&#xff0c;如果是0则无法得到结果&#xff0c;因为此处是乘法 class Solution { public:vector<int> productEx…

Python用于比较数据结构并生成差异报告的工具库之data-diff使用详解

概要 Python的data-diff库是一个用于比较数据结构并生成差异报告的工具。它可以处理各种数据类型,如字典、列表、集合等,使得开发者能够快速识别数据之间的差异。 安装 通过pip可以轻松安装data-diff: pip install data-diff特性 支持多种数据类型:能够比较字典、列表、…

鸿蒙+全国产化工业平板电脑在MES系统采集终端应用

在工业4.0的大浪潮推动下,原有制造行业面临原材料及人工成本上涨、生产现场管理混乱、定单杂、生产效率难以提升、生产异常难以实时监控等诸多因素,根本无法满足数字化工厂的基本需求,更难以与工业4.0接轨。 MES系统是一套面向制造企业车间执行层的生产信息化管理 系统。MES可以…

Mac下用adb命令安装apk到android设备笔记

查询了些资料记录备用。以下是在Mac上使用命令行安装APK文件的步骤&#xff1a; 1. 下载并安装ADB&#xff1a; 如果您的Mac上没有安装ADB&#xff0c;请从官方的Android开发者网站下载Android SDK Platform Tools&#xff1a;Android SDK Platform Tools。将下载的ZIP文件解…

Centos安装MySQL提示公钥尚未安装

一、问题 在Centos7.9使用yum安装MySQL时出现错误&#xff0c;提示&#xff1a;mysql-community-server-5.7.44-1.el7.x86_64.rpm 的公钥尚未安装&#xff0c;如下图所示&#xff1a; 执行命令&#xff1a;systemctl start mysqld也提示错误&#xff1a;Failed to start mysq…

spfa算法(java代码)

题目: 851. spfa求最短路 - AcWing题库 输入样例: 3 3 1 2 5 2 3 -3 1 3 4 输出样例: 2 分析&#xff1a; 先去定义一个class 类似于c里面的pair 里面有两个变量x, y 因为后面需要用优先队列来处理最短路问题需要指出比较x还是y 因此我们让这个pair类实现 Comparable 接口 实…

IP广播对讲系统停车场解决方案

IP广播对讲系统停车场解决方案 一、需求分析 随着国民经济和社会的发展&#xff0c; 选择坐车出行的民众越来越多。在保护交通安全的同时&#xff0c;也给停车场服务部门提出了更高的要求。人们对停车场系统提出了更高的要求与挑战&#xff0c; 需要停车场系统提高工作效率与服…