Mysql 存储引擎设计:xa协议相关接口功能及实现
需要对接的接口以及每个接口的实现
recovery 阶段
此阶段由 xa.cc 文件中的 xarecover_handlerton()
函数完成,它通过三个接口实现与存储引擎的沟通:recover()
,commit_by_xid()
,rollback_by_xid()
。其流程如下:
- 此函数首先已经收集到了最后一个 binlog 文件中成功提交了的事物 xid,将其放入一个 SET 中(具体是不是从最后一个 binlog 文件收集的,怎么收集的,下层存储引擎不需要知道)。
- 调用
recover()
收集存储引擎中处于 prepared 阶段的事务,对于其中的每一个事物的 xid 判断其是否存在于上述 SET 。 - 如果 xid 存在于 SET 中,则调用
commit_by_xid()
。否则则调用rollback_by_xid()
。
/** This function is used to recover X/Open XA distributed transactions.@return number of prepared transactions stored in xid_list */
static int innobase_xa_recover(handlerton *hton, /*!< in: InnoDB handlerton */XA_recover_txn *txn_list, /*!< in/out: prepared transactions */uint len, /*!< in: number of slots in xid_list */MEM_ROOT *mem_root); /*!< in: memory for table names */// init
innobase_hton->recover = innobase_xa_recover;
返回值
表示收集到的事务的数量
*txn_list
用于返回事务链。对于每一个处于prepare 状态的事务,InnoDB 做如下工作:
- 将其事务 xid 写入 txn_list
- 将事务对应的 table 信息 push 入 txn_list
// xid
txn_list->id = *trx->xid;
txn_list->mod_tables = new (mem_root) List<st_handler_tablename>();// tables
for (auto dd_table : trx->mod_tables) {st_handler_tablename *table = new (mem_root) st_handler_tablename();if (!table || get_table_name_info(table, dd_table, mem_root) ||txn_list->mod_tables->push_back(table, mem_root))}
len
表示 txn_list 最长的长度,InnoDB 中如果 prepared 阶段的事务数量达到了 len 个,直接返回。
if (count == len)break;
/** This function is used to commit one X/Open XA distributed transaction which is in the prepared state@return 0 or error number */
static xa_status_code innobase_commit_by_xid(handlerton *hton, /*!< in: InnoDB handlerton */XID *xid); /*!< in: X/Open XA transaction identification */innobase_hton->commit_by_xid = innobase_commit_by_xid;
这个接口由于底层实现原因,可以不用参考 InnoDB 具体的操作,只需要在引擎中完成以下操作即可:
- 对该 xid 对应的事务完成恢复。
- 补充该事务的 commit_record。
/** This function is used to rollback one X/Open XA distributed transactionwhich is in the prepared state@return 0 or error number */
static xa_status_code innobase_rollback_by_xid(handlerton *hton, /*!< in: InnoDB handlerton */XID *xid); /*!< in: X/Open XA transaction identification */innobase_hton->rollback_by_xid = innobase_rollback_by_xid;
直接抛弃 xid 对应的事务,不做恢复。
甚至可以不用实现该接口,在恢复完成后抛弃没有恢复的事务就行。
XID 的设计有点坑:
用于恢复的 xid 本身只是一个 uint64 类型,但 mysql 设计的 xid_t 类型占用了 152 byte 。真正的 xid 被存进了 data 字符数组中。
按道理日志只需要记录 uint64 大小的 xid 就行,但是 xit_t 并没有提供设置其 xid 的办法,只有 set_data() 设置其 data 数据。
目前在 prepare_record 中将整个 xid_t 的内容都存入了(152b),恢复时会恢复一个完整的 xid_t。
#define XIDDATASIZE 128
typedef struct xid_t {private:/**-1 means that the XID is null*/long formatID;/**value from 1 through 64*/long gtrid_length;/**value from 1 through 64*/long bqual_length;/**distributed trx identifier. not \0-terminated.*/char data[XIDDATASIZE];
...
} XID;
prepare 阶段
此阶段只有一个 stage,对应 prepare 接口
/** This function is used to prepare an X/Open XA distributed transaction.@return 0 or error number */
static int innobase_xa_prepare(handlerton *hton, /*!< in: InnoDB handlerton */THD *thd, /*!< in: handle to the MySQL thread ofthe user whose XA transaction shouldbe prepared */bool all); /*!< in: true - prepare transactionfalse - the current SQL statementended */// init
innobase_hton->prepare = innobase_xa_prepare;
此接口需要实现两个功能:
- 判断事务是否需要回滚,如果需要,则返回错误码。
- 如果事务可以正常提交,则生成该事务的日志,生成 prepare_record(其中存储 xid),并等待落盘完成。
commit
分为了三个阶段,三个阶段之间可以并发进行,但每个阶段内顺序运行:第一个进入某个阶段的事务为 leader,后续进入的事务为 follower。leader 所在的线程领导 follower 顺序完成此阶段的任务。
- 其中第一个阶段刷 redo-log,进入这个阶段的所有事务只刷盘一次。除了刷盘 redo-log,bin-log 需要在这个阶段顺序产生,这样一来保证了 redo-log 和 bin-log 日志中事务的顺序是相同的。
- 第二个阶段刷 bin-log
- 第三个阶段执行 commit,顺序调用存储引擎的 commit 接口
/** Flush InnoDB redo logs to the file system.
@param[in] hton InnoDB handlerton
@param[in] binlog_group_flush true if we got invoked by binlog
group commit during flush stage, false in other cases.
@return false */
static bool innobase_flush_logs(handlerton *hton, bool binlog_group_flush);innobase_hton->flush_logs = innobase_flush_logs;
这个接口的作用是等待 redo_log 进行刷盘,是进行组提交的接口。但是测试发现,每一个事务prepare 之后都会调用此接口,且 InnoDB 都会执行刷盘或者等待刷盘操作。
int ha_commit_low(THD *thd, bool all, bool run_after_commit = true);innobase_hton->commit = innobase_commit;
此接口需要实现两个功能:
- 这个接口不需要做回滚操作,如果事务没有执行成功,需要执行回滚,只需要返回一个错误码。mysql 随后会调用
rollback
接口回滚。 - 执行存储引擎的提交操作,并在提交结束后,生成一条 commit_record 日志记录,这里不需要等待此日志记录落盘,因为此日志记录是否落盘不影响已经提交了的事务对应的 tuple 的可见性。且日志的完整性已由 prepare_record 保证。
相关文章:
Mysql 存储引擎设计:xa协议相关接口功能及实现
需要对接的接口以及每个接口的实现 recovery 阶段 此阶段由 xa.cc 文件中的 xarecover_handlerton() 函数完成,它通过三个接口实现与存储引擎的沟通:recover(),commit_by_xid() ,rollback_by_xid()。其流程如下: 此…...

字符串常量池
1.创建对象的思考下面两种创建字符串的方式一样吗?public static void main(String[] args) {//两者一样吗String s1 "hello";String s2 "hello";String s3 new String("hello");String s4 new String("hello");System…...
让技术更有温度,腾讯Light 点亮公益之光
蓝天白云,远处是广东最长跨海大桥——南澳大桥,一艘小船在海面驶过,近处一头中华白海豚露出水面。在第三届腾讯Light技术公益创造营上,海南智渔可持续发展研究中心科学总监郑锐强为我们展现这样一幅人与自然和平相处的美好画面。随…...

电子采购一体化解决方案
企事业数字化转型专家,提供各类应用解决方案。您身边的赋能小助手! 文章目录前言一、当下采购的痛点二、解决方案-供应商管理1.供应商管理三、解决方案-企业询价、供应商报价管理四、解决方案-采购订单五、送货、到货、订单管理总结前言 随着各类产业链…...

SAP COPA 获利能力分析深度解析
一、获利分析配置及相关值概述 二、配置:组织结构 2.1 定义经营范围-KEP8 2.2 维护经营关注点-KEA0 2.3 获利能力分析类型解析 2.4 控制范围分配给经营范围-KEKK 三、配置:数据结构-KEA0 3.1 特征字段 3.1.1 特征字段类别 3.1.2 维护特征字段-K…...

Java学习记录day6
书接上回 类与对象 static关键字 static的作用: 修饰一个属性:声明为static的变量实质上就是一个全局变量,其生命周期为从类被加载开始一直到程序结束;修饰方法:无须本类的对象也可以调用该方法;修饰一个类&#x…...

ubuntu 使用 adb 工具卸载鸿蒙系统预装软件
准备工作 打开 USB 调试 进入 “设置->关于手机” 连续点击版本号, 直到有提示开启了"开发人员选项" 进入 “设置->系统和更新->开发人员选项”, 打开 USB 调式, 顺便可以把"自动系统更新"关了 下载 adb 工具 官方地址: https://developer.an…...

Jmeter in Linux - 在Linux系统使用Jmeter的坑
Jmeter in Linux - 在Linux系统使用Jmeter的坑Jmeter in Linux系列目录:o.a.j.JMeter: Error in NonGUIDriver起因错误分析:解决方案:解析日志没有展示请求和响应信息起因解决方案:注意Jmeter in Linux系列目录: 【如…...

什么是特权访问管理(PAM)
特权访问管理 (PAM) 是指一组 IT 安全管理原则,可帮助企业隔离和管理特权访问、管理特权帐户和凭据、控制谁可以获得对哪些端点的管理访问权限级别,并监视用户对该访问权限执行的操作。 什么是特权访问 特权访问是一种 IT 系统访…...

LeetCode题目笔记——1.两数之和
文章目录题目描述题目难度——简单方法一:暴力代码/Python方法二:哈希表代码/Python代码/C总结题目描述 这道题可以说是力扣的入坑题了,很经典,好像还是面试的经典题。 给定一个整数数组 nums 和一个整数目标值 target,…...
CSDN版的详细MarkDown的使用教程
MarkDown的使用欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释…...

Nextcloud通过不被信任的域名访问解决方法 Nextcloud 您正在访问来自不信任域名的服务器
windows电脑在网页端输入“http://192.168.xxx.xxx:8080/login”访问远程ubuntu18.04服务器,访问其docker镜像的Nextcloud,提示“”Nextcloud通过不被信任的域名访问解决方法 Nextcloud 您正在访问来自不信任域名的服务器“”,如下图…...

Set集合的特点,HashSet去重的几个重要问题
Set集合的特点:无下标,无序(新增顺序和遍历顺序不一致,新增顺序不影响遍历顺序,而且有一个固定顺序),去重(不允许重复记录)public class TestOne {public static void main(String[] args) {// Set集合的特点ÿ…...

云计算|OpenStack|社区版OpenStack安装部署文档(十一--- 如何获取镜像---Rocky版)
前言: 前面我们使用虚拟机搭建了一个openstack集群,也就是在VM虚拟机的基础上模拟了一个简单的基于openstack社区版Rocky的私有云,但,不管任何部署安装工作,最后其实都是需要有实际的应用的,也就是常说的实…...
UmiJS学习
UmiJS4学习笔记起步官网学习:https://umijs.org/开发环境Umi.js 需要使用 Node.js来进行开发,因此请先确保电脑已经安装了 Node.js 且版本在 14 以上。安装pnpm:npm install pnpm -g创建项目Umi 官方提供了一个脚手架 ,可以轻松快…...
Leetcode:322. 零钱兑换(C++)
目录 问题描述: 实现代码与解析: 动态规划(完全背包): 原理思路: 问题描述: 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金…...

C经典小游戏之扫雷
编译环境:VS022 目录 1.算法思路 2.代码模块 2.1 game.h 2.2 game.cpp 2.3 test.cpp 3.重点分析 4.金句省身 1.算法思路 主要采用二维数组进行实现,设置两个二维数组,一个打印结果,即为游戏界面显示的效果,一个用…...

第十节 使用设备树插件实现RGB 灯驱动
Linux4.4 以后引入了动态设备树(Dynamic DeviceTree),我们这里翻译为“设备树插件”。设备树插件可以理解为主设备树的“补丁”它动态的加载到系统中,并被内核识别。例如我们要在系统中增加RGB 驱动,那么我们可以针对R…...
【LeetCode】公交路线 [H](宽度优先遍历)
815. 公交路线 - 力扣(LeetCode) 一、题目 给你一个数组 routes ,表示一系列公交线路,其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。 例如,路线 routes[0] [1, 5, 7] 表示第 …...

报表生成器 FastReport .Net 用户指南 2023(十):Band的属性
FastReport .Net是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案,使用FastReport .NET可以创建独立于应用程序的.NET报表,同时FastReport .Net支持中文、英语等14种语言,可以让你的产品保证真正的国际性。 FastReport.NET官方版…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...

前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...