MySQL中,binlog文件开头的Previous_gtids_log_event是如何计算的

目录

      • [1. 它是什么?](#1. 它是什么?)
      • [2. 它的作用和重要性](#2. 它的作用和重要性)
      • [3. 它是如何计算的?](#3. 它是如何计算的?)
      • [4. 如何查看它?](#4. 如何查看它?)
      • 特殊情况
      • 总结

1. 它是什么?

Previous_gtids_log_event 是一个二进制日志事件,它位于每个 binlog 文件的开头 (在 FORMAT_DESCRIPTION_EVENT 之后)。

它的作用是 记录在当前的 binlog 文件之前,所有已经执行过的 GTID 集合

可以把它理解为 "本文件之前所有 binlog 的 GTID 目录""GTID 上下文"


2. 它的作用和重要性

在 MySQL 启用了 GTID(全局事务标识符) 复制后,Previous_gtids_log_event 变得至关重要。它的主要作用有:

  1. 确定复制起点 :当一个新的从库连接到主库,或者一个已经存在的从库需要重新获取日志时,它会告诉主库"我已经执行过的 GTID 集合是 X"。主库通过对比自己的 Previous_gtids_log_eventGtid_log_event,就能精确地知道应该从哪个 binlog 文件、哪个位置开始发送数据,确保不会重复发送已经执行过的事务,也不会漏掉任何事务。
  2. 保证数据一致性 :它构成了 GTID 的连续性。通过检查所有 binlog 文件的 Previous_gtids_log_event 和文件内部的 Gtid_log_event,可以验证整个复制链的 GTID 集合是否完整、无空洞。
  3. Purge 操作的依据 :MySQL 在自动清理(purge)旧的 binlog 文件时,会确保不会删除任何还包含有从库未执行事务的 binlog 文件。Previous_gtids_log_event 是判断这些依赖关系的关键信息。

3. 它是如何计算的?

Previous_gtids_log_event 的内容是一个 GTID 集合,其计算逻辑非常直观:

它等于上一个 binlog 文件中的 Previous_gtids_log_event 的内容,加上上一个 binlog 文件自身记录的所有 Gtid_log_event

我们可以用一个公式和例子来理解:

计算公式:

当前文件_N 的 Previous_gtids_log_event = 文件_(N-1) 的 Previous_gtids_log_event + 文件_(N-1) 中所有的 GTID

详细示例:

假设我们有三个 binlog 文件:binlog.000001, binlog.000002, binlog.000003

  • binlog.000001

    • Previous_gtids_log_event: 空集合 {}
      • 解释:因为它是第一个文件,在它之前没有任何 GTID 事务。
    • 文件内容:
      • Gtid_log_event: server_uuid:1-1 (事务1)
      • Gtid_log_event: server_uuid:1-2 (事务2)
    • 文件结束时,其包含的完整 GTID 集合为:{server_uuid:1-1, server_uuid:1-2}
  • binlog.000002

    • Previous_gtids_log_event: {server_uuid:1-1, server_uuid:1-2}
      • 解释:这个集合就是上一个文件(binlog.000001)的 Previous_gtids_log_event(空)加上它自己包含的所有 GTID(1-1, 1-2)。
    • 文件内容:
      • Gtid_log_event: server_uuid:1-3 (事务3)
      • Gtid_log_event: server_uuid:1-4 (事务4)
    • 文件结束时,其包含的完整 GTID 集合为:{server_uuid:1-1, server_uuid:1-2, server_uuid:1-3, server_uuid:1-4}
  • binlog.000003

    • Previous_gtids_log_event: {server_uuid:1-1, server_uuid:1-2, server_uuid:1-3, server_uuid:1-4}
      • 解释:这个集合就是上一个文件(binlog.000002)的 Previous_gtids_log_event(1-1, 1-2)加上它自己包含的所有 GTID(1-3, 1-4)。
    • 文件内容:
      • Gtid_log_event: server_uuid:1-5 (事务5)
  • 执行purge binlog to binlog.000003

    • binlog.0000001, binlog.000002被删除
  • binlog.000004

    • 创建新binlog文件
    • Previous_gtids_log_event: {server_uuid:1-1, server_uuid:1-2, server_uuid:1-3, server_uuid:1-4}
      • 解释:这个集合就是上一个文件(binlog.000003)的 Previous_gtids_log_event(1-1, 1-2, 1-3, 1-4)加上它自己包含的所有 GTID(1-5)。
    • 文件内容:(新的 GTID 事务会记录在这里)

4. 如何查看它?

你可以使用 MySQL 官方提供的 mysqlbinlog 工具来查看这个事件。

bash 复制代码
mysqlbinlog binlog.000002 | head -20

在输出的开头部分,你会看到类似这样的内容:

复制代码
# at 4
#240101 10:00:00 server id 1  end_log_pos 123 CRC32 0xabcdefgh
# Position  Timestamp   Type   Master ID        Size      Master Pos    Flags
#       4 9a 8c 7b 5e   0f   01 00 00 00   77 00 00 00   7b 00 00 00   00 00
#       a4 55 0f a8
#       Previous-GTIDs
#       server_uuid:1-4

更清晰的方式是使用 --verbose 选项:

bash 复制代码
mysqlbinlog --verbose binlog.000002 | grep -A 10 "Previous-GTIDs"

输出会直接显示 GTID 集合:

复制代码
# Previous-GTIDs
# server_uuid:1-4

在 MySQL 8.0 及以上版本,你还可以查询 performance_schema 中的 binary_log_transaction_compression_stats 视图(虽然不是直接查询,但可以获取相关信息),或者直接使用 SHOW BINLOG EVENTS 命令,但 mysqlbinlog 是最标准、最清晰的方式。


特殊情况

  • 服务器首次启动 :第一个 binlog 文件的 Previous_gtids_log_event 是空的。
  • 服务器重启 :服务器重启后,会创建一个新的 binlog 文件。这个新文件的 Previous_gtids_log_event 会严格按照上述规则计算,即等于上一个文件的所有 GTID 集合。
  • 手动执行 RESET MASTER :这个命令会清空所有 GTID 执行历史,删除所有 binlog 文件,并从一个全新的、Previous_gtids_log_event 为空的 binlog 文件开始。请在生产环境,尤其是复制环境中极其谨慎地使用此命令。

总结

特性 描述
是什么 一个记录"本文件之前所有 GTID"的事件。
位置 每个 binlog 文件的开头。
作用 确定复制起点、保证 GTID 连续性、辅助 binlog 清理。
计算规则 当前文件_Previous = 上一个文件_Previous + 上一个文件_所有GTID
查看方式 mysqlbinlog <binlog-file>

理解 Previous_gtids_log_event 对于深入掌握 MySQL GTID 复制的工作原理和故障排查非常有帮助。

补充说明:

Q: 新建binlog 文件时,Previous_gtids_log_event可以认为是所有已经执行过的gtid集合 executed gtid set吗?

A: NO. 因为如果事务执行时设置不记录binlog,事务gtid 虽然在executed gtid set中,但不会在binlog文件。所以两者不是等价的。

相关推荐
r***113343 分钟前
如何实现Redis安装与使用的详细教程
数据库·redis·缓存
堇舟44 分钟前
数据库系统原理及应用 第一章 绪论
数据库
Alex Gram1 小时前
Mysql增量同步到PostgreSQL实战
数据库·mysql·postgresql
O***P5711 小时前
【MySQL】MySQL内置函数--日期函数字符串函数数学函数其他相关函数
android·mysql·adb
闲人编程1 小时前
Django缓存策略:Redis、Memcached与数据库缓存对比
数据库·redis·缓存·django·memcached·codecapsule
z***43841 小时前
MySQL-mysql zip安装包配置教程
android·mysql·adb
小二李1 小时前
第8章 Node框架实战篇 - 文件上传与管理
前端·javascript·数据库
z***67771 小时前
macOS安装Redis
数据库·redis·macos
YJlio1 小时前
[编程达人挑战赛] 用 PowerShell 写了一个“电脑一键初始化脚本”:从混乱到可复制的开发环境
数据库·人工智能·电脑