MySQL5.7 中连续 Crash 引发 GTID 丢失

Percona XtraBackup MySQL热备份实战:CentOS 7下零锁表一致性备份方案 MySQL热备份是指数据库持续提供读写服务前提下的物理级一致性备份,其核心原理依赖InnoDB的redo log捕获与崩溃恢复机制模拟,技术价值在于实现RPO<30秒、零业务中断、支持增量与流式传输。典型应用场景包括电商大促数据保护、金融级主从容灾及TB级数据自动化运维。相比mysqldump逻辑备份的锁表风险和LVM快照的内存不一致性,Percona XtraBackup凭借对InnoDB引擎深度适配和CentOS 7环境稳定支持,成为生产环境事实标准。本文聚焦XtraBackup 2.4在CentOS 阅读详情

生产环境中 MySQL 5.7.26 版本下,当主库短时间内连续遇到 2 次 Crash 的特殊场景时报错!

作者:xuty。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1400 字,预计阅读需要 5 分钟。

问题现象

生产环境中 MySQL 5.7.26 版本下,当主库短时间内连续遇到 2 次 Crash 的特殊场景时,会导致备库重新建立复制时会抛出错误 Slave has more GTIDs than the master has,IO 线程复制报错。

2023-12-11T10:32:43.433707+08:00 1457551 [ERROR] Error reading packet from server for channel '': Slave has more GTIDs than the master has, using the master's SERVER_UUID. This may indicate that the end of the binary log was truncated or that the last binary log file was lost, e.g., after a power or disk failure when sync_binlog != 1. The master may or may not have rolled back transactions that were already replicated to the slave. Suggest to replicate any transactions that master has rolled back from slave to master, and/or commit empty transactions on master to account for transactions that have been (server_errno=1236)

如下图所示,备库比主库多了几十万个 GTID,且解析对应 Binlog 都是业务操作,更像是主库把这部分 GTID“丢掉了”;

  • 主库:1-1080678246;

  • 备库:1-1081067155;

问题分析

先来复习下 MySQL 5.7 GTID 持久化原理:

  • gtid_executed 变量:它是一个处于内存中的 GTID SET,表示数据库中执行了那些 GTID,会实时更新,但是一旦重启就会丢失。show slave status 的 Executed_Gtid_Set 和 show master status 中的 Executed_Gtid_Set 都来自于这个变量。
  • mysql.gtid_executed 表: GTID 持久化的介质,只有在 binlog 切换时才会触发更新。将该 binlog 中的 GTID SET 记录到表中,所以该表中会记录所有历史 binlog 中的 GTID SET。

📌当 MySQL 启动时,会初始化 gtid_executed 变量。通过读取 mysql.gtid_executed 表的持久化记录(已持久化的 GTID),再加上扫描最后一个 binlog 的 GTID(未持久化的 GTID)合并后完成初始化,新的 GTID 会基于 gtid_executed 变量递增产生。

基于上述 GTID 持久化的原理,我们就有理由怀疑是主库没有持久化最后 1 个 binlog 中的所有 GTID,导致备库比主库多了很多的 GTID。

通过对比 Crash 前后的 binlog 中 GTID,发现主库确实并没有持久化到 mysql-bin.001499 中的 binlog,导致后续新产生的 GTID 反而比之前的还小。(正常情况下 GTID 肯定是随着 binlog 越来越大的)。

GDB 调试复现

基于 MySQL 5.7.26 版本,通过GDB调试模拟复现了上述问题现象,主库连续崩溃恢复后会丢失最后1个binlog中的GTID,引发备库GTID大于主库。

先讲下原因:

  1. 在mysql 第一次崩溃恢复过程中,会先创建新的binlog,再将崩溃前最后1个binlog中的GTID持久化到表中;
  2. 如果在这个间隙,再次发生崩溃,就可能会导致mysql已经产生了新的binlog,但是还未将第一次崩溃前最后1个binlog持久化到表中;
  3. mysql再次启动时,就不会再读取第一次崩溃前最后1个binlog做持久化了,而是读取新产生的binlog作持久化,那么就会丢失第一次崩溃前最后1个binlog中的GTID ;
#mysql5.7.26 crash启动流程
|main
 |mysqld_main
  |ha_recover         #mysqld.cc:4256 恢复数据流程
  |open_binlog        #mysqld.cc:4282 生成新的binlog
  |Gtid_state::save   #mysqld.cc:4870 读取最后1个binlog写入mysql.gtid_executed
   |Gtid_table_persistor::save
    |Gtid_table_persistor::write_row

本地 GDB 模拟复现过程

  1. 使用 MySQL 5.7.26 mysqld-debug 版本启动 MySQL。

  1. 连入 MySQL,创建 test库,生成 1 个GTID。当前 binlog 为 mysql-bin.000001,mysql.gtid_executed 表为空,GTID 还未持久化。

  1. kill -9 mysql 进程模拟 OOM。

  1. 使用 GDB 启动 MySQL,并打了2个断点,分别是MYSQL_BIN_LOG::open_binlog(创建新的binlog) 和 Gtid_state::save(崩溃启动过程中持久化最后1个binlog的GTID);

  1. RUN开始,会停在第一个断点 MYSQL_BIN_LOG::open_binlog 处,此时可以看到还未产生新的 binlog。

  1. continue 继续跑,会卡在第二个断点 Gtid_state::save,此时已经生成了新的 binlog,但是还未将 mysql-bin.000001 中的 GTID 持久化。

  1. 正常情况下 Gtid_state::save 走完,就会把 mysql-bin.000001 中的 GTID 持久化到表中,这里模拟把 mysql 给 kill 了,此时产生了新的 binlog 但是还未做完 GTID 持久化。

  1. 再次正常启动 MySQL,就会发现“丢掉了”mysql-bin.000001 中的 GTID,此次启动并不会再次读取 mysql-bin.000001 中的 GTID 做持久化;所以备库会比主库多整整 1 个 binlog 的 GTID。

同样的测试在 MySQL v5.7.26、v5.7.36、v5.7.44 均可以复现,说明 MySQL 5.7 中都存在该现象。而 MySQL 8.0 因为 GTID 持久化做了优化,所以不会有此类问题。

总结

在 MySQL 5.7 版本下,因为 GTID 持久化机制的原因,当 MySQL 处于崩溃恢复阶段时,如果再次遇到 Crash,就可能会丢失最后 1 个 binlog 中的 GTID。

更多技术文章,请访问:https://opensource.actionsky.com/

关于 SQLE

SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。

✨ Github:https://github.com/actiontech/sqle

📚 文档:https://actiontech.github.io/sqle-docs/

💻 官网:https://opensource.actionsky.com/sqle/

👥 微信群:请添加小助手加入 ActionOpenSource

🔗 商业支持:https://www.actionsky.com/sqle

[F2F] MySQL相关 覆盖索引:在某个查询里面,索引 k 已经“覆盖了”我们的查询需求,称为覆盖索引。覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。索引下推:MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。 阅读详情

相关推荐

MySQL实例crash的案例详细分析

【问题描述】 我们生产环境有一组集群的多台MySQL服务器(MySQL 5.6.21),不定期的会crash,但error log中只记录了重启信息,未记录crash时的堆栈: mysqld_safe Number of processes running now: 0 mysqld_safe mysqld restarted 接下来首先排查系统日志/var/log/message文件,crash时没有其他异常信息,也不是OOM导致的。 【排查思路】 由于日志中未记录有价值的信息。为定位crash的原因,首先开启mysql core dump的功能。 下面是开启core dump的步骤

MySQL 数据库崩溃(crash)的常见原因和解决办法

墨墨导读:本文来自墨天轮用户投稿,详述MySQL 数据库崩溃(crash)的常见原因和解决办法,希望对大家有帮助。数据技术嘉年华,十周年盛大开启,点我立即报名!大会以“自研·智能·新基建...

Enmotech的博客 4927

Verilog除法器(32位无符号+带符号)

32位无符号除法器设计 恢复余数法: 恢复余数除法的基本思路是从“部分余数”中减去除数,如果结果为负(不够减),则恢复原来的部分余数,商0. 寄存器使用: reg_r 存放被除数a reg_b 存放除数b reg_r 存放余数(初始清零) 具体做法: 做减法时,减数是reg_b中的除数,被减数是reg_r中的余数左移一位,最低位由reg_q(被除数)的最高位补充。为了能够判断相减结果的正...

qq_38600065的博客 1万+

mysql crash_MySQL Crash 问题处理思路

MySQL Crash 问题处理思路(一)当发生Crash 时 error log 没有日志信息,这时候需要查看/var/log/messages这种情况一般是发生在MySQL进程被强制杀死,发生在下列的两种情形之一:1. kill -9命令如果是被kill-9强制杀死的,/var/log/messages会有类似如下输出内容:May11 06:10:44 localhost systemd: m...

weixin_39636707的博客 803

VsCode+JLink+GCC替代Keil开发GD32程序-个人总结

对个人使用vscode+Jlink开发GD32程序做了总结,供需要者参考。

MyCollege1999的博客 2763

coze+飞书多维表格,批量分析小红书笔记,关键还能获取图片(附保姆级教程)

通过coze工作流,一键同步小红书账号和笔记链接到飞书多维表格,效率飞升~

qq_24403067的博客 4175

MySQL 数据库崩溃(crash)的常见原因和解决办法---发表到 《数据和云》 公众号

文章目录检查mysql数据库的启动时间检查mysql服务状态检查mysql中的uptime状态使用ps检查进程启动时间检查mysql日志MySQL 数据库 crash的常见原因mysql的bug 检查mysql数据库的启动时间 linux系统中的systemd会在mysqld进程crash后自动重新启动mysql的服务,需要注意的是使用kill -9杀死mysqld进程系统会自动重新启动,而只使用kill命令则不会重新启动,因为执行kill命令,系统会发送一个SIGTERM信号给mysqld,mysql数据

姚远OracleACE的博客 1万+

芯片缺陷检测全流程:从光学成像到AI自动判别的实战路线

在半导体制造中,良率是衡量产线效率的核心指标,而缺陷检测则是守住良率的关键防线。传统人工显微镜目检已难以应对微米级乃至纳米级缺陷的挑战,工业界正加速转向机器视觉与深度学习相结合的技术方案。其核心原理在于:先通过明场、暗场或DIC等光学成像获取高对比度图像,再借助传统图像处理算法快速提取候选缺陷区域,最后利用CNN等深度学习模型对缺陷进行精准分类与判定。这一技术路线不仅大幅提升检测效率与准确性,还能有效降低漏检和误报,广泛应用于晶圆制造、封装测试等环节。本文从成像选型、算法分工、数据标注到模型部署,系统梳理了

weixin_29053577的博客 265

第55期:MySQL 频繁 Crash 怎么办?

针对该问题 MySQL Crush,其实问题原因有很多。ChatDBA 能够罗列出decimal字段可能导致该问题也是因为 ChatDBA 底层的知识库足够丰富,后续我们也将持续补充数据库领域更多的专业知识。回到该问题,是由于两个字段没有获取到有效值,而且他们的数据类型为decimal类型,当进行数值转换的时候触发了 MySQL 的 bug 导致崩溃。最后配合业务方针对该情况提前做数据判断,防止异常值直接入库来避免该问题的出现。

ActionTech的博客 1058

人大金仓V8R3企业版License更新全攻略:从查看到重启一步到位

本文详细解析了人大金仓V8R3企业版License更新的完整运维流程,涵盖从诊断当前授权状态、获取与验证新文件、精准定位旧文件路径,到安全替换文件及服务重启验证的全过程。重点针对更新流程中常见的版本匹配、文件定位、权限与服务重启等关键环节提供了实战解决方案和避坑指南,帮助运维人员高效、平稳地完成授权续期。

redis7keeper的博客 899

几率大的网络安全面试题(含答案)

其他篇章:Java校招极大几率出的面试题(含答案)----汇总 本文面试题汇总: 防范常见的 Web 攻击 重要协议分布层 arp协议的工作原理 rip协议是什么?rip的工作原理 什么是RARP?工作原理 OSPF协议?OSPF的工作原理 TCP与UDP区别总结 什么是三次握手四次挥手? tcp为什么要三次握手? dns是什么?dns的工作原理 一次完整的HTTP请求过程 Cookies和ses...

睶 6万+

mysql crash 如何定位_MySQL实例crash的案例详细分析

【问题描述】我们生产环境有一组集群的多台MySQL服务器(MySQL 5.6.21),不定期的会crash,但error log中只记录了重启信息,未记录crash时的堆栈:mysqld_safe Number of processes running now: 0mysqld_safe mysqld restarted接下来首先排查系统日志/var/log/message文件,crash时没有其...

weixin_29469195的博客 294

跨越边界:用MessagePipe实现无缝的进程间通信

MessagePipe是一个用于.NET平台的消息传递库,它专注于简化异步消息处理和进程间通信。通过提供一系列易于使用的API,开发者可以快速搭建起稳定可靠的通信管道,支持多种传输协议(如TCP、Unix域套接字等),并内置了序列化/反序列化功能,使得跨语言和跨平台的数据交换变得轻而易举。为了方便序列化和反序列化操作,我们需要为每种消息定义对应的类或结构体,并标记属性。这样可以确保消息在发送方和接收方之间正确无误地传递。[Key0set;[Key1set;

墨夶的博客 816

mysql宕机后gtid丢失_MySQL启用Gtid时如何确保Slave crash safe

背景MySQL5.6 支持slave crash safe特性,根据之前对slave crash safe特性的认识,在配置了以下参数的情况下,可以保证slave crash后保证数据的一致性。relay_log_info_repository = TABLErelay_log_recovery = ON但是,用MySQL5.6(Percona Server 5....

weixin_42202716的博客 399

【数据分析】基于多组学数据整合的微生物与宿主互作网络构建及可视化分析

综上所述,本教程通过详细的步骤和方法,展示了如何整合微生物群落数据、宿主基因表达数据和代谢组数据,构建微生物与宿主互作网络,并进行可视化分析。这种方法为研究微生物与宿主之间的复杂关系提供了一种有力的工具,有助于推动相关疾病的研究和治疗。然而,在实际应用中,需要注意数据处理和分析过程中的各种问题,并结合实验验证来提高研究结果的可靠性和科学性。未来,随着多组学技术的不断发展和完善,以及数据分析方法的创新,相信我们能够更深入地理解微生物与宿主之间的互作机制,为疾病的预防、诊断和治疗提供更有力的支持。

专注生信领域 370

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

mysql5.7—基于GTID的半同步复制

扩展 前面我们已经了解并配置过了mysql5.7的主从复制与基于GTID的主从复制,今天我们再来认识一种MYSQL的复制—半同步复制,又是一种复制,MYSQL到底有多少种复制呢?我们先来看看MySQL的复制架构衍生史。 MySQL的复制分为四种: 1: 普通的replication,异步同步。 搭建简单,使用非常广泛,从mysql诞生之初,就产生了这种架构,性能非常好,可谓非常成熟。 但是这...

gd0306的博客 695

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

mysql 8.0关闭binlog_从MySQL 8.0故障恢复看InnoDB及Binlog角色变化

最近在调试MySQL新功能发现MySQL 8.0相比5.7版本在mysqld crash recovery上有较大不同点,有必要记录下。主要包括事务gtid持久化到mysql.gtid_executed方式和InnoDB在其中发挥的作用。并延伸分析未来MySQL版本对InnoDB的定位。MySQL 5.7故障恢复逻辑关于这块实现,网上有很多文章,这里不再展开,结合下图直接说主逻辑:1. MySQL...

weixin_42117485的博客 305

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

MySQl新特性 GTID

GTID简介 概念 全局事务标识符(GTID)是创建的唯一标识符,并与在源(主)服务器上提交的每个事务相关联。此标识符不但是唯一的,而且在给定复制设置中的所有服务器上都是唯一的。所有交易和所有GTID之间都有一对一的映射关系。GTID由source_id和transaction_id组成 GTID = source_id:transaction_id s...

weixin_30700099的博客 112

mysql5.6新语法_mysql5.6复制新特性

一、名词解释:1:server_uuid:服务器身份ID。在第一次启动Mysql时,会自动生成一个server_uuid并写入到数据目录下auto.cnf文件里,官方不建议修改。[root@mysql5_6 data]# pwd/usr/local/mysql/data[root@mysql5_6 data]# cat auto.cnf[auto]server-uuid=b0869d03-d4a9...

weixin_33167915的博客 184

mysql5.6 replication_mysql5.6 replication配置

一、名词解释:1:server_uuid:服务器身份ID。在第一次启动Mysql时,会自动生成一个server_uuid并写入到数据目录下auto.cnf文件里,官方不建议修改。[root@mysql5_6 data]# pwd/usr/local/mysql/data[root@mysql5_6 data]# cat auto.cnf[auto]server-uuid=b0869d03-d4a9...

weixin_31920157的博客 260

深入理解 MySQL 半同步复制:AFTER_SYNC 为何能避免主从同步数据丢失?

MySQL 5.7+默认采用AFTER_SYNC半同步复制模式,确保客户端收到"提交成功"后数据永不丢失。该模式将binlog持久化和从库确认置于InnoDB提交之前,即使主库崩溃也能通过崩溃恢复机制保证数据一致性。相比5.6的AFTER_COMMIT模式,AFTER_SYNC解决了"成功响应后数据仍可能丢失"的问题。配置需配合sync_binlog=1等参数,但需注意半同步并非全同步,存在自动降级为异步复制的可能。这是MySQL在性能和数据安全间的最佳平衡方案。

不会骑摩托的程序员不是好的摄影师 992

7.Innodb底层原理与Mysql日志机制深入剖析

[mysqld] 启用二进制日志(5.7需显式开启,8.0默认开启) log-bin=mysql-bin 设置binlog格式(ROW模式最安全) binlog-format=ROW 设置日志过期天数(默认0表示不自动删除) expire_logs_days=7 每个日志文件大小(默认1GB) max_binlog_size=100M ### ✅2. 三种日志格式对比 | 格式类型 | 说明 | 优点 | 缺点 | 示例 | |---------|------|------|------|------| |

D_AKJS 367

怎么跳出 MySQL 的10个大坑(下)

MySQL · 优化改进· 复制性能改进过程 前言 与oracle 不同,MySQL 的主库与备库的同步是通过 binlog 实现的,而redo日志只做为MySQL 实例的crash recovery使用。MySQL在4.x 的时候放弃redo 的同步策略而引入 binlog的同步,一个重要原因是为了兼容其它非事务存储引擎,否则主备同步是没有办法进行的。 redo 日

521

MySQL-8.0.20

版本: 8.0.20 操作: Centos 7 Linux 未介绍针对数据库的详细操作,如有需求请前往 第一章 MySQL的介绍及安装 1、介绍 1.1 数据库管理系统(DBMS) RDBMS : Oracle SQLServer DB2 MySQL NoSQL : Redis MongoDB ES NewSQL: PolarDB OceanBase TDB TiDB 1.2 排名 db-engines.com/ranking 1.3 MySQL 介绍 1.3.1 如何获取软件 www.my

有用的话关个注,点个赞,收个藏🫶。 664

mysql备份恢复操作手册

备份方式: 数据库备份的分类; 物理备份: 指对数据库操作系统的物理文件(数据文件、日志文件)等的备份; 冷备份: 必须在数据库关闭的状态下进行备份,能够更好的保证数据库的完整性; 热备份: 能够在数据库处于正常运行的情况下备份,能够更高的保证服务的可用性; 逻辑备份: 指对数据库的逻辑组件(数据库、表、数据对象)进行备份; 完全备份: 将数据进行完整的备份,包含完整的库、表、索引、视图等,需要花...

企业实战系列集 ●●● https://ximenjianxue.blog.youkuaiyun.com 1199

MySQL 进阶03

文章目录五、存储引擎1.种类2.innodb引擎的优点3.事务(ACID)4.事务的生命周期5.隔离级别6.mysql如何防止不可重复读(RR模式下)7.mysql如何防止幻读(RR模式下)六、日志和备份恢复1.日志2.备份恢复七、mysql主从1.搭建2.原理(简单版本)3.原理(复杂版本)八、数据库架构1.最开始的主从2.读写分离架构的主从3.高可用架构4.分布式架构 -----转自 【王者-...

OldBoy Python学习笔记 322
上一篇: 遇到 MySQL 死锁问题如何解决?
下一篇: 在 MySQL 事务中,什么时候释放锁?
爱可生开源社区
博客等级 码龄8年 1936粉丝 1004原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值