server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息 。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里 。InnoDB 会维护自己的 savepoint 链表,里面保存着 trx_named_savept_t 对象 。1.undo 日志序号InnoDB 的事务对象有一个名为 undo_no 的属性 。事务每次改变(插入、更新、删除)某个表的一条记录 , 都会产生一条 undo 日志 。这条 undo 日志中会存储它自己的序号 。这个序号就来源于事务对象的 undo_no 属性 。
也就是说,事务对象的 undo_no 属性中保存着事务改变(插入、更新、删除)某个表中下一条记录产生的 undo 日志的序号 。
每个事务都维护着各自独立的 undo 日志序号,和其它事务无关 。
每个事务的 undo 日志序号都从 0 开始 。事务产生的第 1 条 undo 日志的序号为 0,第 2 条 undo 日志的序号为 1 , 依此类推 。
InnoDB 的 savepoint 结构中会保存创建 savepoint 时事务对象的 undo_no 属性值 。2.savepoint 结构我们通过 SQL 语句创建一个 savepoint 时 , server 层、binlog、InnoDB 会各自创建用于保存 savepoint 信息的结构 。
server 层的 savepoint 结构是一个 SAVEPOINT 类型的对象 , 主要属性如下:
- prev:指向 server 层的 savepoint 链表中,上一次创建的 SAVEPOINT 对象 。
- name:savepoint 的名字 。
- mdl_savepoint:创建这个 savepoint 之前,事务加了哪些 MDL 锁 。binlog 的 savepoint 结构很简单,是一个 8 字节的整数 。这个整数的值,是创建 savepoint 时事务已经产生的 binlog 日志的字节数,也是接下来新产生的 binlog 日志写入 trx_cache 的 offset 。
InnoDB 的 savepoint 结构是一个 trx_named_savept_t 类型的对象,主要属性如下:
- name:InnoDB 的 savepoint 名字 。这个名字是 InnoDB 自己生成的,和 server 层的 SAVEPOINT 对象中保存的 savepoint 名字不一样 。
- savept:也是一个对象,类型为 trx_savept_t,里面保存着创建 savepoint 时,事务对象的 undo_no 属性值 。
- trx_savepoints:InnoDB 中多个 trx_named_savept_t 对象形成的链表 。创建 savepoint 时 , server 层会分配一块 96 字节的内存,除了存放它自己的 SAVEPOINT 对象,还会存放 binlog offset 和 InnoDB 的 trx_named_savept_t 对象 。
文章插图
图片
3.查找同名 savepoint客户端连接到 MySQL 之后 , MySQL 会分配一个专门用于该连接的用户线程 。
用户线程中有一个 m_savepoints 链表,用户创建的多个 savepoint 通过 prev 属性形成链表,m_savepoints 就指向最新创建的 savepoint 。
文章插图
图片
server 层创建 savepoint 之前,会按照创建时间从新到老,逐个查看链表中是否存在和本次创建的 savepoint 同名的 savepoint 。
4.删除同名 savepoint如果在用户线程的 m_savepoints 链表中找到了和本次创建的 savepoint 同名的 savepoint,需要先删除 m_savepoints 链表中的同名 savepoint 。
找到的同名 savepoint,是 server 层的 SAVEPOINT 对象,它后面的内存区域分别保存着 InnoDB 的 trx_named_savept_t 对象、binlog offset 。
binlog 是个老实孩子,乖乖的把 binlog offset 写入了 server 层为它分配的内存里 。删除同名 savepoint 时,不需要单独处理 binlog offset 。
InnoDB 就不老实了,虽然 server 层也为 InnoDB 的 trx_named_savept_t 对象分配了内存,但是 InnoDB 并没有往里面写入内容 。
事务执行过程中 , 用户每次创建一个 savepoint,InnoDB 都会创建一个对应的 trx_named_savept_t 对象,并加入 InnoDB 事务对象的 trx_savepoints 链表的末尾 。
因为 InnoDB 自己维护了一个存放 savepoint 结构的链表,server 层删除同名 savepoint 时,InnoDB 需要找到这个链表中对应的 savepoint 结构并删除 , 流程如下:
- server 层把同名 savepoint 的 SAVEPOINT 对象后面分配给 trx_named_savept_t 对象的内存地址传给 InnoDB 。
- InnoDB 根据自己的算法把内存地址转换为字符串,作为 InnoDB 的 savepoint 名字 , 到事务对象的 trx_savepoints 链表中找到对应的 trx_named_savept_t 对象,并从链表中删除该对象 。
推荐阅读
- 创造与魔法搬家cd多久,创造与魔法家园核心成员怎么设置
- MySQL 核心模块揭秘,你看明白了吗?
- 东航坠机事故,你关心的十大核心问题是什么
- ie浏览器一直弹出修复工具,QQ浏览器怎么设置漏洞模块拦截
- 十八项核心制度闭环管理是什么意思 十八项核心制度闭环管理是什么意思呀
- 从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
- 功率模块自热阻和耦合热阻区别 功率模块自热阻和耦合热阻区别是什么
- 准线上事故之MySQL优化器索引选错
- 什么是网络中的路由器?核心功能解释
- MySQL数据恢复,你会吗?