MySQL · 捉虫动态 · Relay log 中 GTID group 完整性检测

本文涉及的产品
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介: bug背景 官方 5.7.6 版本对 gtid 有非常多的改进和bugfix,其中有一个 bugfix 是针对 relay log 中没有接收完整的 gtid 事务的。正常的relay log 中的 gtid 事务应该是像下面这样: 1. gtid event 2. query event (

bug背景

官方 5.7.6 版本对 gtid 有非常多的改进和bugfix,其中有一个 bugfix 是针对 relay log 中没有接收完整的 gtid 事务的。正常的relay log 中的 gtid 事务应该是像下面这样:
1. gtid event
2. query event (begin)
3. row event (write/update/delete)
4. query event (commit)

上面这 4 个 event 序列构成一个 group。因为 IO 线程从主库接收 binlog 时,是以 event 为单位的,如果在 group 中间,比如3之后,stop slave 停掉IO线程的话,relay log 中就会记录一个不完整的事务。我们知道,GTID 的 auto_position 协议是通过计算主备库之间 GTID 集合的差集,然后来确定哪些 binlog 是要从主发给备的,备库用的集合就是 Retrieved_Gtid_Set 和 gtid_executed 的并集。IO 线程收到一个 gtid event 就会把它加入到 Retrieved_Gtid_Set 中,所以如果这个时候 start slave的话,最后这个不完整的事务是不会重新发送的,因为根据协议,主库认为备库已经有了这个事务,不需要再发送了。

修复分析

之所以会出现这种问题,是因为 IO 线程在处理的时候,没有将 gtid_event 和后面的事件序列当作一个整体来看待,只要收到开头的 gtid event,就认为整个 group 都已经收到。

所以官方的修复就是加一个事务边界检查器(Transaction_boundary_parser),只有当 IO 线程收到完整的 group,才将 gtid 加入到 Retrieved_Gtid_Set;同样在 mysqld 重启从 relay log 中初始化 Retrieved_Gtid_Set 时,也利用边界检查器判断 realy log 中的 gtid 事务是否完整。

下面就看下这个边界检查器是如何做判断的:

将 relay log 中的 event 序列分为2种,DDL 和 DML。

DDL 序列如下:
  DDL-1: GTID event
  DDL-2: User_var/Intvar/Rand event
  DDL-3: Query event

DML 序列如下:
  DML-1: GTID event
  DML-2: Query event(BEGIN)
  DML-3: Query event(除了 BEGIN/COMMIT/ROLLBACK) / Rows event / load event)
  DML-4: (Query event (COMMIT) | Query event(ROLLBACK) | Xid)

然后定义了5种状态,标识目前读到的 event 事件是在事务内还是事务外。
1. EVENT_PARSER_NONE // 在事务外,这个时候应该是读完 DDL-3 或者 DML-4
2. EVENT_PARSER_GTID // 读到了GTID event,处于事务中,这个时候应该是读到 DDL-1 或者 DDL-3
3. EVENT_PARSER_DDL // 处于事务中,读到 DDL-2
4. EVENT_PARSER_DML // 处于事务中,读到 DML-2 或者 DML-3
5. EVENT_PARSER_ERROR // 错误状态

边界检查器的实现是一个状态机,根据目前所处的状态和读到的event,确定下一步应该转移到什么状态。

比如对于下面这样的 event 序列:
1. gtid
2. begin
3. update rows
4. commit

状态是这样转移的,刚开始是 EVENT_PARSER_NONE,读到事件1,转为 EVENT_PARSER_GTID 状态,读到事件2,转为 EVENT_PARSER_DML 状态,读到事件3,转为EVENT_PARSER_DML状态,读到事件4,转为 EVENT_PARSER_NONE 状态。从EVENT_PARSER_NONE(事务外)最终又到 EVENT_PARSER_NONE,中间读了一个完整的事务。
详细的状态转移规则可以看官方patch

有了这个边界检测器后,IO 线程就能准确判断当前是处于事务外还是事务内,从而决定要不要把GTID添加到 Retrieved_Gtid_Set 中。

相关bug

对于 relay log 部分事务的问题,官方之前有个patch,其逻辑是对 relay log 中最后一个 gtid 做特殊处理。在 request dump 的时候,如果这个 gtid 不在备库的 gtid_executed 集合中的话,就把这个 gtid 从发送给主库的 gtid 集合里去掉,这样主库就会把这个最后的 gtid 事务重新发过来;如果这个 gtid 已经在备库的 gtid_executed 集合中的话,就不从发送给主库的 gtid 集合里去掉,这样主库库就不会重发。

但是这种修复方式依赖于 gtid_executed,并不是根据事务是否完整来决定要不要重拉事务,所以有的场景下会有问题,如 bug#72392 这种场景。

官方目前这种用边界检测的修复方式是比较好的,但是可能会有性能上的问题,因为每个的 event 都要用边界检查器判断下,像 query event 需要要进行字符串比较。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
|
存储 关系型数据库 MySQL
|
2月前
|
API C# 开发框架
WPF与Web服务集成大揭秘:手把手教你调用RESTful API,客户端与服务器端优劣对比全解析!
【8月更文挑战第31天】在现代软件开发中,WPF 和 Web 服务各具特色。WPF 以其出色的界面展示能力受到欢迎,而 Web 服务则凭借跨平台和易维护性在互联网应用中占有一席之地。本文探讨了 WPF 如何通过 HttpClient 类调用 RESTful API,并展示了基于 ASP.NET Core 的 Web 服务如何实现同样的功能。通过对比分析,揭示了两者各自的优缺点:WPF 客户端直接处理数据,减轻服务器负担,但需处理网络异常;Web 服务则能利用服务器端功能如缓存和权限验证,但可能增加服务器负载。希望本文能帮助开发者根据具体需求选择合适的技术方案。
68 0
|
2月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
69 0
|
2月前
|
存储 关系型数据库 MySQL
深入MySQL:事务日志redo log详解与实践
【8月更文挑战第24天】在MySQL的InnoDB存储引擎中,为确保事务的持久性和数据一致性,采用了redo log(重做日志)机制。redo log记录了所有数据修改,在系统崩溃后可通过它恢复未完成的事务。它由内存中的redo log buffer和磁盘上的redo log file组成。事务修改先写入buffer,再异步刷新至磁盘,最后提交事务。若系统崩溃,InnoDB通过redo log重放已提交事务并利用undo log回滚未提交事务,确保数据完整。理解redo log工作流程有助于优化数据库性能和确保数据安全。
221 0
|
2月前
|
存储 SQL 关系型数据库
MySQL事务日志奥秘:undo log大揭秘,一文让你彻底解锁!
【8月更文挑战第24天】本文深入探讨了MySQL中undo log的关键作用及其在确保事务原子性和一致性方面的机制。MySQL通过记录事务前的数据状态,在需要时能回滚至初始状态。主要介绍InnoDB存储引擎下的undo log实现,包括undo segment和record的结构,而MyISAM则采用redo log保障持久性而非一致性。通过一个简单的SQL回滚示例,展示了undo log如何在实际操作中发挥作用,帮助读者更好地理解并运用MySQL事务管理功能。
145 0
|
3月前
|
SQL 存储 监控
(十一)MySQL日志篇之undo-log、redo-log、bin-log.....傻傻分不清!
任何项目都会有日志,MySQL也不例外,而且MySQL更是其中的佼佼者,日志种类繁多,而本篇的目的就是全解MySQL中的各类日志,如撤销日志、错误日志、慢查询日志、中继日志、回滚日志.....
206 1
|
2月前
|
监控 安全 Linux
在Linux中,如何查看和审计系统日志文件以检测异常活动?
在Linux中,如何查看和审计系统日志文件以检测异常活动?
|
3月前
|
Oracle 关系型数据库
Log Archive Destinations to a Group
oracle 归档日志路径配置
21 1
|
4月前
|
SQL 运维 关系型数据库
|
4月前
|
存储 关系型数据库 MySQL

相关产品

  • 云数据库 RDS MySQL 版
  • 下一篇
    无影云桌面