事务的起源:事务池和管理器的初始化

爱可生开源社区 2024 全新技术专栏《MySQL 核心模块揭秘》第一期。

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

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

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

1. 事务池和管理器

作为 MySQL 中支持事务的默认存储引擎,InnoDB 对表中数据的读写操作都在事务中执行。

MySQL 被设计为支持高并发,支持很多客户端同时连接到数据库,这些连接可以同时执行 SQL。

如果这些 SQL 都要读写 InnoDB 表,InnoDB 会为每个连接启动一个事务,这意味着需要同时启动很多事务。

对于 TP 场景,通常情况下,事务都会很快执行完成。启动事务、执行 SQL、提交事务的整个流程只会持续很短的时间。

TP 是 OLTP 的简称,表示在线事务处理;与之相对的另一个常用术语 AP,是 OLAP 的简称,表示在线事务分析。

以这样一个场景为例:

  • 客户端连接到 MySQL。
  • 客户端执行 begin 语句。
  • 客户端执行一条 update 语句,按主键 ID 更新一条记录。
    这个步骤中,InnoDB 会在执行 update 语句之前,真正启动一个事务。
  • 客户端执行 commit 语句。
  • 客户端关闭数据库连接。InnoDB 会在这一步释放事务。

在这个场景下,InnoDB 事务从启动到释放的整个生命周期,有可能只持续 1 ~ 2 毫秒(甚至更短)。

由于要存放事务 ID、事务状态、Undo 日志编号、事务所属的用户线程等信息,每个事务都有一个与之对应的对象,我们称之为事务对象

每个事务对象都要占用内存,如果每启动一个事务都要为事务对象分配内存,释放事务时又要释放内存,会降低数据库性能。

为了避免频繁分配、释放内存对数据库性能产生影响,InnoDB 引入了事务池(Pool),用于管理事务。

顾名思义,事务池是一个池子,这个池子存放的东西既不是水,也不是酒,而是事务对象。

对比我们生活中的各种池子,例如:水池、洗手池、池塘,都是有大小限制的。

事务池也一样有大小限制,不能无限制的存放事务对象。数据库繁忙的时候,有很多很多事务对象,需要多个事务池来管理。

事务池多了之后,又会引发另一些问题,例如:

  • 怎么创建新的事务池?
  • 客户端创建了一个新的数据库连接,要获取一个新的事务对象,从哪个事务池获取?
  • 其它问题...

为了解决这些问题,InnoDB 又引入了事务池管理器(PoolManager),用于管理事务池。

MySQL 启动过程中,InnoDB 先创建事务池管理器,然后,事务池管理器创建并初始事务池。

2. 创建事务池管理器

InnoDB 整个生命周期中,事务池管理器只有一个,它有个很重要的属性(m_size),用于指定每个事务池能用多大内存来存放事务对象。

这个属性值来源于一个硬编码的常量值,代码里是这样定义的:

/** Size of on trx_t pool in bytes. */
static const ulint MAX_TRX_BLOCK_SIZE = 1024 * 1024 * 4;

这意味着每个事务池能用来存放事务对象的内存是 4194304 字节,也就是 4M。

MySQL 启动过程中,事务池管理器只会创建并初始化一个事务池。

这个事务池会放入事务池管理器的 m_pools 属性。这个属性是个数组(vector),用于管理所有事务池。

创建事务池的过程中,InnoDB 会分配一块 4M 的内存用于存放事务对象。

每个事务对象的大小为 992 字节,4M 内存能够存放 4194304 / 992 = 4228 个事务对象。

3. 初始化事务池

事务池创建完成之后,就该初始化了。事务池的初始化,主要是为了得到一些事务对象。

事务池有一个队列,用于存放已经初始化的事务对象。我们称这个队列为事务队列

一个事务池有 4M 内存可以存放事务对象,这块内存会被分隔成 4228 个小块。每初始化一块小内存,就会得到一个事务对象,这个事务对象会被放入事务队列。

InnoDB 初始化事务池的过程中,不会初始化全部的 4228 块小内存,只会初始化最前面的 16 块小内存,得到 16 个事务对象并放入事务队列。

初始事务池完成之后,事务队列中只有 16 个事务对象。

那么,剩余的 4212 块小内存什么时候会被初始化?

它们会在这种情况下被初始化:启动过程中初始化的 16 个事务对象都被取走使用了,事务队列变成空队列了。

此时,需要再分配一个事务对象用于启动新事务,InnoDB 就会把剩余的 4212 块小内存全部初始化,得到 4212 个事务对象并放入事务队列。

有一点需要说明,不管是启动过程中初始化的 16 块小内存,还是运行过程中初始化的 4212 块小内存,都是在循环里一个一个初始化的。每一轮循环都要干两件事:

  • 初始化一块小内存,得到一个事务对象。
  • 把事务对象放入事务池的事务队列中。

初始化小块内存的过程中,会初始化事务对象的各个属性。这里我们就不一一介绍这些属性了,等到该它们出场的时候,再按需介绍。

4. 总结

InnoDB 只有一个事务池管理器,用于管理 N 个事务池(N >= 1),每个事务池可以管理 4228 个事务对象。

MySQL 启动过程中,InnoDB 会先创建事务管理器。事务管理器会创建一个事务池,初始化 16 个事务对象放入事务池的事务队列。

MySQL 运行过程中,如果这 16 个事务对象都正在被使用,InnoDB 需要一个新的事务对象时,会一次性初始化剩余的 4212 个事务对象并放入事务池的事务队列。

本期问题:运行过程中,创建一个新的事务池,会分配多少内存?初始化多少个事务对象?
关于本期主题,如果大家有任何疑问,欢迎留言交流!

下期预告:BEGIN 语句会马上启动事务吗?

更多技术文章,请访问: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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/597212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

即时设计:一键查看设计稿与页面差异,让设计师的工作更便捷高效

设计稿走查 在设计工作中,对设计稿和实际页面进行对比是必不可少的环节。然而,传统的对比方式往往耗时耗力,无法精确测量差异。为了解决这个问题,我们推出了一款强大的工具,它可以通过图片对比,轻松查看设…

使用results.csv文件数据绘制mAP对比图

yolov5每次train完成(如果没有中途退出)都会在run目录下生成expX目录(X代表生成结果次数 第一次训练完成生成exp0 第二次生成exp1…以此类推)。expX目录下会保存训练生成的weights以及result.txt文件,其中weights是训练…

Clickhouse 为什么快

ClickHouse是一个用于联机分析处理(OLAP)的开源列式数据库管理系统(DBMS)。它之所以能提供出色的查询性能和处理速度,主要归功于以下几个方面的设计和优化: 列式存储 ClickHouse存储数据按列而不是按行组织…

Redis第3讲——跳跃表详解

一、什么是跳跃表 跳跃表(skiplist)是一种随机化的数据结构,由William Pugh在论文《Skip lists: a probabilistic alternative to balanced trees》中提出。它通过在每个节点中维持多个指向其它节点的指针,从而达到快速访问节点的…

Zabbix 监控介绍

1、功能概述 通常所说的监控,会模糊地包含以上下个细分领域的内容: 应用性能监控(Application Performance Monitoring)业务交易监控(Business Transaction Monitoring)网络性能监控(Network …

华为云CES监控与飞书通知

华为云负载均衡连接数监控与飞书通知 在云服务的日常运维中,持续监控资源状态是保障系统稳定性的关键步骤之一。本文通过一个实际案例展示了如何使用华为云的Go SDK获取负载均衡器的连接数,并通过飞书Webhook发送通知到团队群组,以便运维人员…

福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!

千里之行,始于足下,若想提高软件编程能力,最最重要的是实践,所谓纸上得来终觉浅,绝知此事要躬行。根据相关【艾宾浩斯遗忘曲线】研究表明,如果不动手实践,记住的东西会很快忘记。 为了便于大家查…

C#设计模式之观察者模式

前言 观察者(Observer)模式也称发布-订阅(Publish-Subscribe)模式,定义了对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 观察者模式的图解如下所示…

Iterable 对象转换为 Stream 对象

在 Java 8 中,可以使用 Stream API 来对集合进行操作。要将 Iterable 对象转换为 Stream 对象,可以使用 StreamSupport 类的 stream() 方法。具体来说,可以按照以下步骤进行转换: 调用 Spliterators.spliteratorUnknownSize(iter…

设计安全高效网络的17个关键策略

随着越来越多的业务流程走向数字化,拥有一个强大可靠的网络能够处理日益增长的日常流量对于维持生产力和服务至关重要。同时,网络攻击者永远不会停滞不前,每家组织都是潜在的目标。 技术领导者及其团队比以往任何时候更知道设计一种网络架构…

小程序测试和APP测试的区别

今天看了一下关于如何测试小程序的教学视频,里面讨论了一个很经典的面试题:小程序测试和APP测试的区别,包括在之前的面试过程中也确实是遇到过这个问题,所以这次打算把它记录下来,也算是知识巩固了。 首先从测试的内容…

android7以上 代码安装APK

一、所需权限 <!--请求安装APK的权限--> <uses-permission android:name"android.permission.REQUEST_INSTALL_PACKAGES" /> <!--写如外部存储的权限--> <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"…

【DevOps-03】Build阶段-Maven安装配置

一、简要说明 下载安装JDK8下载安装Maven二、复制准备一台虚拟机 1、VM虚拟复制克隆一台机器 2、启动刚克隆的虚拟机,修改IP地址 刚刚克隆的虚拟机 ,IP地址和原虚拟的IP地址是一样的,需要修改克隆后的虚拟机IP地址,以免IP地址冲突。 # 编辑修改IP地址 $ vi /etc/sysconfig…

内存管理的概念-第四十一天

目录 前言 内存空间的分配与回收 内存空间的扩展 地址转换 存储保护 上下限寄存器 重定位寄存器和界地址寄存器 本节思维导图 前言 操作系统作为系统资源的管理者&#xff0c;当然也需要对内存进行管理&#xff0c;要管理什么呢&#xff1f; 操作系统复杂内存空间的分…

Lazada商品详情API(lazada.item_get)进行商品的实时更新

一、引言 在数字时代&#xff0c;电商平台如Lazada成为了商品交易的重要场所。为了保持竞争力&#xff0c;实时更新商品信息变得至关重要。Lazada提供的商品详情API&#xff08;lazada.item_get&#xff09;为开发者提供了一个高效的方式来获取并更新商品数据。本文将深入探讨…

RH850从0搭建Autosar开发环境【52】- Davinci Configurator拓展之手动添加Can接收与发送报文(下)

Davinci Configurator拓展之手动添加Can接收与发送报文 一、COM模块1.添加Rx signal2.添加Tx signal3.添加COM IPDU - Rx4.添加COM IPDU - Tx二、PDUR模块1.添加PduRRoutingPath_MyRx2.添加PduRRoutingPath_MyTx三、查看配置参数总结完善拓展的能力建设,在Configurator里面手动…

SpringBoot全局Controller返回值格式统一处理

一、Controller返回值格式统一 1、WebResult类 在 Controller对外提供服务的时候&#xff0c;我们都需要统一返回值格式。一般定义一个 WebResult类。 统一返回值&#xff08;WebResult类&#xff09;格式如下&#xff1a; {"success": true,"code": 2…

从vue小白到高手,从一个内容管理网站开始实战开发第四天,使用Element UI构建页面-页面路由的配置-登录(二)

昨天我们在项目中创建了一个登录页面,但是发现登录页面无法打开,始终显示vue的默认页面。昨天也说了是因为我们没有给项目配置路由,那么今天我们就看看怎么给我们的项目配置路由,让我们可以通过浏览器的地址栏来访问到我们的页面。 一、项目正式开发前的准备工作 之前我们…

prometheus 基本配置介绍

文章目录 前传globalalertingrule_filesscrape_configs外传 前传 prometheus grafana的安装使用&#xff1a;https://nanxiang.blog.csdn.net/article/details/135384541 本文说下监控nginx&#xff0c;prometheus grafana nginx 安装配置和使用 Docker 镜像下载地址&#x…

数据库-创建表

create table 表的名字([表定义选项]表定义选项 (列名1 类型 &#xff0c;列名2 类型&#xff0c;…&#xff0c;n 类型】 create table Class(class_id int ,class_name varchar(128),class_teachar varchar(64)) ;create table 表的名字([表定义选项][表的单选项] [表的分区…