MySql binlog 可以有多个打开的事务吗?

Posted

技术标签:

【中文标题】MySql binlog 可以有多个打开的事务吗?【英文标题】:Can MySql binlog have more than one open transaction? 【发布时间】:2022-01-23 23:56:40 【问题描述】:

mysql binlog 是否可以同时有多个打开的事务(= 不同事务的事件在 binlog 中交错)?

XID event 包含事务 ID,但没有表示事务开始的事件并且包含事务 ID。我将“和”加粗,因为其中有带有查询“BEGIN”的 QUERY 事件,但它没有说明它属于哪个事务。

或者即使数据库中有几个处于活动状态,mysql也会在binlog中序列化事务?

查看 debezium 来源 here 似乎答案是否定的,但我希望在 mysql 或官方文档的来源中看到确认。

【问题讨论】:

【参考方案1】:

对于常规事务,二进制日志不能包含任何未提交的事务。数据更改在提交之前不会写入二进制日志。

但是 XA 交易是不同的。 XID 事件是 XA 事务的一部分。二进制日志中可能有多个“已准备好”的 XA 事务。

https://dev.mysql.com/doc/refman/5.7/en/xa-restrictions.html 说:

请注意,事务的初始部分(由 XA_prepare_log_event 标识)之后不一定是其 XA COMMIT 或 XA ROLLBACK,这可能导致任何两个 XA 事务的交错二进制日志记录。

这并没有明确说明二进制日志可以包含多个打开的 XA 事务,但它是隐含的。如果一次只能有一个活动,那么 XA 事务交错是没有意义的。

请注意,这适用于 MySQL 5.7.7 及更高版本。早期版本的 MySQL 根本不支持二进制日志记录 XA 事务。

如果你想阅读源代码,它在sql/xa.cc。

【讨论】:

(叹气)是的,我完全忘记了 XA 事务,它破坏了我的简单实现:(谢谢你指出这一点,比尔。【参考方案2】:

首先,我们必须注意,“事务”是特定引擎的功能。 InnoDB 是人们使用的主要引擎,所以我将重点介绍它。

是的,当然可以有多个事务,因为如果没有你就永远不会出现死锁。

但是binlog doesn't include anything that wasn't committed:

在语句或事务完成后但在任何锁被释放或任何提交完成之前立即完成二进制日志记录。这可确保日志按提交顺序记录。

因此,事务日志本质上是序列化的。

MariaDB has some InnoDB documentation 包括:

您最多可以修改 96 * 1023 个并发事务的数据 生成撤消记录。在 128 个回滚段中,InnoDB 为临时修改事务的非重做日志分配 32 表和相关对象,减少最大并发数 数据修改事务从 128.000 增加到 96,000。极限是 所有数据修改事务时 32,000 个并发事务 还要修改临时表。

日志的目的是能够通过重播已完成的语句和事务来从灾难性损失中恢复。如果恢复通过事务日志并且从未提交事务,则该事务不在事务日志中。

【讨论】:

回滚段、二进制日志和事务日志都是独立的东西。 @BillKarwin 我在哪里说的? 问题是关于二进制日志的,但您的答案包括有关回滚段(也称为撤消日志)的信息,然后是有关事务日志的信息。 也许你对这个话题已经不感兴趣了,但是与binlog有关的源文件是:binlog.hbinlog.cclog_event_hlog_event.cc。 如果 2 阶段提交的存在意味着你不能简单地实现你想要做的任何事情,很好,但是 XA 和 2 阶段提交设置在我的mysql使用世界的经验。

以上是关于MySql binlog 可以有多个打开的事务吗?的主要内容,如果未能解决你的问题,请参考以下文章

阿里年薪百万数据库面试MySQL会丢数据吗?

什么是MySQL binlog

数据库篇:mysql日志类型之 redo、undo、binlog

mysql 只有binlog 怎么恢复

MySQL的Binlog与主从复制

在哪里可以找到 MySQL 事务日志?