MySQL 核心模块揭秘 | 03 期 | 我是一个事务,请给我一个对象

2024-01-21

每个事务都有一个对象,这篇文章我们聊聊,事务的对象从哪里来,要到哪里去。

作者:操盛春,爱可生技术专家,公众号『一树一溪』作者,专注于研究 MySQL 和 OceanBase 源码。

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

在这里插入图片描述

本文基于 MySQL 8.0.32 源码,存储引擎为 InnoDB。

1. 用户事务和内部事务

InnoDB 读写表中数据的操作都在事务中执行,开始一个事务的方式有两种:

  • 手动:通过 BEGIN START TRANSACTION 语句以及它们的扩展形式开始一个事务。
  • 自动:直接执行一条 SQL 语句,InnoDB 会自动开始一个事务,SQL 语句执行完成之后,又会自动提交这个事务。

这两种方式开始的事务,都用来执行用户 SQL 语句,属于 用户事务

InnoDB 有时候也需要自己执行一些 SQL 语句,为了和用户 SQL 做区分,我们把这些 SQL 称为内部 SQL。

内部 SQL 也需要在事务中执行,执行这些 SQL 的事务就是 内部事务

InnoDB 有几种场景会使用内部事务,以下是其中主要的三种:

  • 如果上次关闭 MySQL 时有未提交,或者正在提交但未提交完成的事务,启动过程中,InnoDB 会把这些事务恢复为内部事务,然后提交或者回滚。
  • 后台线程执行一些操作时,需要在内部事务中执行内部 SQL。

    以 ib_dict_stats 线程为例,它计算各表、索引的统计信息之后,会使用内部事务执行内部 SQL,更新 mysql.innodb_table_stats、mysql.innodb_index_stats 表中的统计信息。
  • 为了实现原子操作,DDL 语句执行过程中,InnoDB 会使用内部事务执行内部 SQL,插入一些数据到 mysql.innodb_ddl_log 表中。

2. 分配事务对象

InnoDB 用事务池来管理事务对象,用事务池管理器来管理事务池。

不管是用户事务,还是内部事务,真正启动事务之前,都需要通过事务池管理器从某个事务池的 事务队列 中分配一个事务对象。

已经创建的那些事务池,都放在事务池管理器的 m_pools 数组中。分配事务对象时,先从第 1 个事务池开始,过程是这样的:

  • 如果事务池的事务队列中有可用的事务对象,直接分配一个就好了。
  • 否则,看看事务池中还有没有未初始化的小块内存。
  • 如果有,那就好办了,把这些小块内存全部初始化,得到的事务对象都放入该事务池的事务队列,并从中分配一个事务对象。
  • 否则,继续对下一个事务池,走一遍上面的流程。
  • 要是没有下一个事务池,怎么办?
  • 也好办,那就创建一个新事务池,初始化之后,就可以直接从它的事务队列中分配一个事务对象了。

3. 再做一些初始化工作

分配一个事务对象,得到的是一个出厂设置的对象,这个对象的各属性值都已经是初始状态了。

分配事务对象之后,InnoDB 还会对事务对象的几个属性再做一次初始化工作,把这几个属性再一次设置为初始值,其实就是对这些属性做了重复的赋值操作。

这些属性中,有必要提一下的是事务状态( trx->state )。出厂设置的事务对象,事务状态是 TRX_STATE_NOT_STARTED ,表示事务还没有开始。

我们执行 show engine innodb status 可能会看到类似下面的内容:

LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 281480261177256, not started
0 lock struct(s), heap size 1192, 0 row lock(s)

其中, not started 就来源于事务的 TRX_STATE_NOT_STARTED 状态。

除了给几个属性重复赋值,还会改变另外两个属性的值:

  • trx->in_innodb:给这个属性值加上 TRX_FORCE_ROLLBACK_DISABLE 标志,防止这个事务被其它线程触发回滚操作。事务后续执行过程中,这个标志可能会被清除,我们就不展开介绍了。
  • trx->lock.autoinc_locks:分配一块内存空间,用于存放 autoinc 锁结构。事务执行过程中需要为 auto_increment 字段生成自增值时使用。

4. 加入事务链表

我们查询 information_schema.innodb_trx 表,能看到当前正在执行的事务有哪些,这些事务来源于两个链表。

为用户事务分配一个事务对象之后,还有一件非常重要的事,就是把事务对象放入其中一个链表的最前面,代码是这样的:

UT_LIST_ADD_FIRST(trx_sys->mysql_trx_list, trx);

从上面的代码可以看到,这个链表就是 trx_sys->mysql_trx_list ,它只会记录用户事务。

至于内部事务,并不会放入 trx_sys->mysql_trx_list 链表。等到真正启动事务时,事务对象会被放入另一个链表,我们先按下不表,留个悬念,后面的内容会介绍。

5. 总结

InnoDB 把事务分为用户事务和内部事务,给事务分配对象时,会按照这个顺序:

  • 先从事务池的事务队列中分配一个对象。
  • 如果事务队列中没有可用的事务对象,就初始化事务池的剩余小块内存,从得到的事务对象中分配一个对象。
  • 如果所有事务池都没有剩余未初始化的小块内存,就创建一个新的事务池,并从中分配一个事务对象。

本期问题 :InnoDB 怎么没有把内部事务也放入 trx_sys->mysql_trx_list 链表?欢迎大家留言交流。

下期预告 :准备那么久,终于要启动 InnoDB 事务了。

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

关于 SQLE

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

SQLE 获取

类型 地址
版本库 https://github.com/actiontech/sqle
文档 https://actiontech.github.io/sqle-docs/
发布信息 https://github.com/actiontech/sqle/releases
数据审核插件开发文档 https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL 核心模块揭秘 | 03 期 | 我是一个事务,请给我一个对象 的相关文章

  • 为通用字符选择表排序规则

    我正在开发一个需要存储通用字符的后端 我选择了utf8mb4用于此目的的表编码 我还必须选择表格排序规则 最直接的选择是选择utf8mb4 general ci表整理 除了一般的排序规则之外 还有大约20种其他排序规则可供选择 更具体的排序
  • 使用单个查询和每用户密码盐进行用户登录

    我决定使用存储在数据库中的每用户盐来实现用户登录 盐作为密码的前缀 该密码使用 SHA 进行哈希处理并存储在数据库中 过去 当我不使用盐时 我会使用典型的方法 使用用户输入的用户名和密码来计算查询返回的行数 然而 对于每个用户的盐 您需要先
  • 在 MySQL 表中存储用户密码的最佳 PHP 哈希方法?

    我已经阅读 Stack Overflow 问题大约 15 分钟了 每一个问题似乎都与我之前读到的问题相矛盾 Bcrypt SHA1 MD5 等 我目前对我的密码进行 MD5 但我想让我的数据库在发生泄露时更加安全 我知道这个问题已经被问了一
  • Mysql 连接到服务器:用户 root@localhost 的访问被拒绝

    edit9 是否有可能我只是缺少文件夹的一些权限 我真的非常非常感谢更多的建议 edit3 由于这篇文章没有得到足够的回复 而且这绝对是至关重要的 我尽快完成这件事 我重建了我的帖子以显示我认为到目前为止我已经扣除的内容 注意 通过许多不同
  • 更新或插入 MySQL Python

    如果记录已存在 我需要更新一行 如果不存在 我需要创建一个新记录 我理解 ON DUPLICATE KEY 将使用 MYSQLdb 完成此操作 但是我无法使其正常工作 我的代码如下 cursor database cursor cursor
  • 使用子查询与 LEFT JOIN 一起选择 MAX 值

    我有一个获取搜索结果的查询 效果很好 查询成功示例 SELECT individuals individual id individuals unique id TIMESTAMPDIFF YEAR individuals day of b
  • 获取jdbc中表依赖顺序

    我在 MySQL 数据库中有一组表 A B C D 依赖关系如下 B gt C gt A 和 D gt A 也就是说 A 有一个 PrimaryKey C 有一个外键指向 A 的主键 B 有一个外键指向 C 的主键 类似地 D 有一个外键指
  • 如何使用Peewee查询多个相似的数据库?

    我遇到了使用 Peewee 查询多个数据库的问题 我有 2 个现有的 mysql 数据库 让我们将它们命名为 A 和 B 结构相似 因为它是两个 Bugzilla 数据库 我使用 Pwiz 生成模型 modelsA py 和 modelsB
  • MySQL 查询获取每小时计数

    我需要统计每小时发生的操作次数 我的数据库按操作的时间戳保存日志 我明白我可以做一个 SELECT table time COUNT table time from table t group by t time 然而 也有一段时间没有采取
  • 测验程序的 MySql 数据库设计

    我目前正在开发一个项目 主要是创建一个测验应用程序 它将能够进行包含 10 到 20 个问题的多项选择题或简答题的测验 它需要能够根据正确答案检查用户的答案 然后对用户的答案进行评分 稍后 我可能会实现一个后端功能来在线创建测验 但现在我将
  • 多个数据库连接

    我有三张桌子 categories content info and content The categories表包含类别的id及其 IDparent类别 The content info包含两列 entry id帖子的 ID 和cat
  • 解析错误:语法错误,意外的“”(T_ENCAPSED_AND_WHITESPACE)[重复]

    这个问题在这里已经有答案了 完整错误 解析错误 语法错误 意外的 T ENCAPSED AND WHITESPACE 需要标识符 T STRING 或 变量 T VARIABLE 或数字 T NUM STRING 它说错误出现在第 12 行
  • MyISAM 方言生成错误的 DDL

    我们使用 MyISAM 方言org hibernate dialect MySQLMyISAMDialect使用JPA2自动生成DDL文件3 6 9 FinalMySQL 5 5 数据库上的 hibernate 提供程序 The creat
  • 如何将值从 android 传递到 php Web 服务并检索它?

    我正在尝试将一个值传递给我的 php web 服务 我已经使用此代码来传递 名称 值 private class MyAsyncTask extends AsyncTask
  • PHP 数据库显示在具有不同锚标记的相同字段中

    我四处寻找 看看这是否可行 但却空手而归 首先 这是我的代码 div style display none div ul li li li li li li ul
  • 如何删除非空约束?

    假设创建了一个表 如下所示 create table testTable colA int not null 您将如何删除非空约束 我正在寻找类似的东西 ALTER TABLE testTable ALTER COLUMN colA DRO
  • iPhone表情插入MySQL却变成空值

    我们正在开发一个 iPhone 应用程序 它将表情符号从 iPhone 发送到服务器端 PHP 并插入到 MySQL 表中 我正在做服务器端的工作 但是insert语句执行成功后 插入的值变成空了 我可以正确插入字段 varchar 的是文
  • 在关系数据库中存储树结构的已知方法有哪些? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何列出表中的所有列?

    对于各种流行的数据库系统 如何列出表中的所有列 对于 MySQL 请使用 DESCRIBE name of table 只要您使用 SQL Plus 或 Oracle 的 SQL Developer 这也适用于 Oracle
  • php echo 不工作

    我的代码似乎不起作用 单选按钮出现 但旁边什么也没有 似乎 mysql fetch array 由于某种原因无法工作 因为我已经玩过代码并反复测试它以查找代码似乎遇到的位置出现问题并停止工作 有人可以告诉我出了什么问题吗 欢呼声我是新手 最

随机推荐

  • 基于opencv的大米计数统计(详细处理流程+代码)

    在我每周的标准作业清单中 有一项是编写计算机视觉算法来计算该图像中米粒的数量 因此 当我的一个好朋友M给我发了一张纸上的扁豆照片 显然是受到上述转发的启发 请我帮他数一下谷物的数量时 它勾起了我怀旧的回忆 因此 我在我的旧硬盘上寻找很久以前
  • 渗透测试常用工具汇总_渗透测试实战

    1 Wireshark Wireshark 前称Ethereal 是一个网络分包分析软件 是世界上使用最多的网络协议分析器 Wireshark 兼容所有主要的操作系统 如 Windows Linux macOS 和 Solaris kali
  • 网络安全基础知识面试题库

    1 基于路由器的攻击手段 1 1 源IP地址欺骗式攻击 入侵者从外部传输一个伪装成来自内部主机的数据包 数据包的IP是 内网的合法IP 对策 丢弃所有来自路由器外端口 却使用内部源地址的数据包 1 2 源路由攻击 入侵者让数据包循着一个不可
  • 毕业设计- 基于深度学习的小样本时间序列预测算法 - Attention

    目录 前言 课题背景与意义 课题实现 一 数据集 二 设计思路 三 相关代码示例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校
  • 毕业设计:基于卷积神经网络的验证码识别系统 机器视觉 人工智能

    目录 前言 设计思路 一 课题背景与意义 二 算法理论原理 2 1 字符分割算法 2 2 深度学习 三 检测的实现 3 1 数据集 3 2 实验环境搭建 3 3 实验及结果分析 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实
  • 毕业设计:基于深度学习的微博谣言检测系统 人工智能

    目录 前言 设计思路 一 课题背景与意义 二 算法理论原理 三 检测的实现 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有
  • 还在手工标注数据集?快来试一试自动化多模型标注大模型-gui交互式标注(部署运行教程-高效生产力)

    快速入门指南 先看一下自动化标注的强大 简直医学图像处理的福音呀 不仅如此 任何区域都可以识别到 面对任意开集数据 都可以达到良好的效果 运行模式 目前 X AnyLabeling 支持两种运行方式 一种是下载源码直接运行 另一种是直接下载
  • 【毕业设计选题】复杂背景下的无人机(UVA)夜间目标检测系统 python 人工智能 深度学习

    前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度的 对本科同学来说是充满挑战 为帮助大家顺利通过和节省时间
  • 无人机视角、多模态、模型剪枝、国产AI芯片部署

    无人机视角 多模态 模型剪枝 国产AI芯片部署是当前无人机技术领域的重要研究方向 其原理和应用价值在以下几个方面进行详细讲述 一 无人机视角 无人机视角是指在无人机上搭载摄像头等设备 通过航拍图像获取环境信息 并进行图像处理和分析 这种技术
  • 网络安全:绕过 MSF 的一次渗透测试

    这次渗透的主站是 一个 Discuz 3 4 的搭建 违法招 piao 网站 配置有宝塔 WAF 用 Discuz ML 3 X 的漏洞进行攻击 但是没有成功 发现主站外链会有一个发卡网 引导人们来这充值 是 某某发卡网 而且域名指向也是主
  • 毕业设计:基于卷积神经网络的图像分类系统 python人工智能

    目录 前言 设计思路 一 课题背景与意义 二 算法理论原理 2 1 卷积神经网络 2 2 SVM算法 三 检测的实现 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力
  • 台积电再被坑,2纳米光刻机优先给Intel和三星,美国太霸道了

    外媒指出今年ASML的10台2纳米光刻机分配已经基本确定了 Intel拿到6台 三星获得3台 台积电只能得到一台 考虑到美国对ASML的强大影响力 外媒的这些消息应该有较高的可信性 Intel在先进工艺制程方面 自从2014年量产14纳米之
  • iPhone成中国市场2023年最畅销手机,但国产手机已雄起

    苹果首次夺下国内手机市场年度第一名 iPhone成中国市场最畅销的手机 这个话题突然热起来 其实iPhone一直都是中国市场最畅销的手机啊 不过2023年Q4显示出国产手机已经雄起啦 苹果在2023年首次夺下中国手机市场年度第一名 这对苹果
  • 【计算机毕业设计】OA公文发文管理系统_xtv98

    近年来 人们的生活方式以网络为主题不断进化 OA公文发文管理就是其中的一部分 现在 无论是大型的还是小型的网站 都随处可见 不知不觉中已经成为我们生活中不可或缺的存在 随着社会的发展 除了对系统的需求外 我们还要促进经济发展 提高工作效率
  • 华为重夺第一,竞争对手就降价,这真的是巧合么?

    2024年Q4某国产手机品牌重夺国产手机品牌第一名 不过2024年开年第一周 国内手机市场的格局再次大变 华为夺下了第一名 不仅超越众多国产手机品牌 还超过了苹果 给国内手机市场带来震动 首先降价的是苹果 苹果的iPhone15自去年上市以
  • 回乡翻新父辈房子成部分年轻人的选择,低成本的田园生活

    独家首发 所谓城市套路深 我要回农村 这个或许只是一部分人的调侃 然而却有一部分年轻人做出这样的选择 不过他们又不希望花费太大成本 如此一些年轻人就选择翻新父母留下的旧房子 对于这部分年轻人来说 其实这也是一种不错的选择 城市里生活压力大
  • 性能大减80%,英伟达芯片在华“遇冷”,我方霸气回应:不强求

    中国这么大一块市场 谁看了不眼馋 在科技实力大于一切的今天 高端芯片的重要性不言而喻 作为半导体产业发展过程中不可或缺的一环 芯片技术也一直是我国技术发展的一大 心病 在美西方等国的联手压制下 我国芯片技术发展处处受阻 至今也未能在高端芯片
  • 作物叶片病害识别系统

    介绍 由于植物疾病的检测在农业领域中起着重要作用 因为植物疾病是相当自然的现象 如果在这个领域不采取适当的护理措施 就会对植物产生严重影响 进而影响相关产品的质量 数量或产量 植物疾病会引起疾病的周期性爆发 导致大规模死亡 这些问题需要在初
  • 京东001号快递员,刘强东给的买房承诺,仅4年时间就实现了

    京东001号快递员金宜财正式退休 不知是有意还是无意 他成为了互联网的热搜 不过大众更关心的是金宜财当年得到刘强东的承诺 只要干几年就能买房 那么刘强东的承诺有没有实现 又是如何实现的呢 据悉当年京东刚开始推京东快递的时候 京东还没什么名气
  • MySQL 核心模块揭秘 | 03 期 | 我是一个事务,请给我一个对象

    每个事务都有一个对象 这篇文章我们聊聊 事务的对象从哪里来 要到哪里去 作者 操盛春 爱可生技术专家 公众号 一树一溪 作者 专注于研究 MySQL 和 OceanBase 源码 爱可生开源社区出品 原创内容未经授权不得随意使用 转载请联系