MySQL的XID

XID是什么

MySQL Binlog 文件由 event 组成,event 有不同的类型,而XID_EVENT 表示一个事务的提交操作。

当事务提交时,在 binlog 依赖的内部 XA 中,额外添加了 Xid 结构,binlog 有多种数据类型:

  1. statement 格式,记录为基本语句,包含 Commit
  2. row 格式,记录为基于行
  3. mixed 格式,日志记录使用混合格式

不论是 statement 还是 row 格式,binlog 都会添加一个 XID_EVENT 作为事务的结束,该事件记录了事务的 ID 也就是 Xid,在 MySQL 进行崩溃恢复时根据 binlog 中提交的情况来决定如何恢复。

XID如何生成

MySQL 内部维护了一个全局变量 global_query_id,每次执行语句的时候将它赋值给 Query_id,然后给这个变量加 1。如果当前语句是这个事务执行的第一条语句,那么 MySQL 还会同时把 Query_id 赋值给这个事务的 Xid。

XID是唯一的吗

而 global_query_id 是一个纯内存变量,重启之后就清零了。所以你就知道了,在同一个数据库实例中,不同事务的 Xid 也是有可能相同的。

但是 MySQL 重启之后会重新生成新的 binlog 文件,这就保证了,同一个 binlog 文件里,Xid 一定是惟一的。

虽然 MySQL 重启不会导致同一个 binlog 里面出现两个相同的 Xid,但是如果 global_query_id 达到上限后,就会继续从 0 开始计数。从理论上讲,还是就会出现同一个 binlog 里面出现相同 Xid 的场景。

因为 global_query_id 定义的长度是 8 个字节,这个自增值的上限是 2^64-1。要出现这种情况,必须是下面这样的过程:

执行一个事务,假设 Xid 是 A;

接下来执行 2^64次查询语句,让 global_query_id 回到 A;

再启动一个事务,这个事务的 Xid 也是 A。

不过,2^64这个值太大了,大到你可以认为这个可能性只会存在于理论上。

XID的作用

二阶段提交

步骤如下

  • InnoDB 进入 Prepare 阶段,并且 write/sync redo log,写 redo log,将事务的 xid 写入到 redo 日志中,binlog 不作任何操作

  • 进行 write/sync binlog,写 binlog 日志,也会把 xid 写入到 binlog

  • 调用 InnoDB 引擎的 commit 完成事务的提交,将 commit 信息写入到 redo 日志中

MySQL崩溃恢复会有什么操作

如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;

如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:

a. 如果是,则提交事务;

b. 否则,回滚事务。

MySQL 怎么知道 binlog 是完整的

一个事务的 binlog 是有完整格式的:statement 格式的 binlog,最后会有 COMMIT;

row 格式的 binlog,最后会有一个 XID event。

崩溃恢复的时候,会按顺序扫描 redo log:

如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;

如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。

MySQL解释如下

扫描最后一个binlog获取XID生成一个hash table,再扫描redo将checkpoint之后所有XID,如果XID在hash table里面则提交,不在则回滚。

相关推荐

  1. MySQLXID

    2024-04-08 17:46:01       40 阅读
  2. XML语言学习记录5- XSD

    2024-04-08 17:46:01       45 阅读
  3. 探索 Xind3 生态系统,解锁铭文资产新玩法

    2024-04-08 17:46:01       59 阅读
  4. msSQLMySQL区别?

    2024-04-08 17:46:01       73 阅读
  5. Postgresql源码(120)事务XID分配与主备XID同步

    2024-04-08 17:46:01       47 阅读
  6. gen_arrow_contour_xld

    2024-04-08 17:46:01       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-08 17:46:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-08 17:46:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-08 17:46:01       82 阅读
  4. Python语言-面向对象

    2024-04-08 17:46:01       91 阅读

热门阅读

  1. QT6 Android设置程序图标及名称

    2024-04-08 17:46:01       36 阅读
  2. extern “C“的作用

    2024-04-08 17:46:01       33 阅读
  3. js有哪些常用的跳转页面方法(补)

    2024-04-08 17:46:01       30 阅读
  4. 2024.4.8每日一题

    2024-04-08 17:46:01       40 阅读
  5. go 使用pprof查看内存分布

    2024-04-08 17:46:01       38 阅读
  6. PostgreSQL的|| 和::

    2024-04-08 17:46:01       38 阅读
  7. python实现两个二维数组相加

    2024-04-08 17:46:01       33 阅读
  8. 【Python】RocketMQ 基础使用

    2024-04-08 17:46:01       26 阅读
  9. Bash Scripting Tutorial for Beginners - medium synoposis

    2024-04-08 17:46:01       37 阅读
  10. A Random Walk Based Anonymous Peer-to-Peer

    2024-04-08 17:46:01       23 阅读