龙空技术网

6 张图吃透Undo log,MySQL进阶必知必会!

程序员宝妹儿 1147

前言:

此时同学们对“mysql必知必会pdf英语版下载”大概比较注意,看官们都想要知道一些“mysql必知必会pdf英语版下载”的相关资讯。那么小编同时在网摘上网罗了一些有关“mysql必知必会pdf英语版下载””的相关资讯,希望各位老铁们能喜欢,你们一起来学习一下吧!

Undo log 回滚日志是很重要的知识点, MySQL 进阶必知必会,大厂面试高频问题。

Undo Log 回滚日志记录事务执行过程中的旧值,当事务发生异常、需要回滚操作时,可使用 Undo Log 来撤销事务的变更操作,将数据恢复到事务开始之前的状态,从而确保事务的一致性,提高数据库的并发性能和系统的稳定性。

大家好,我是爱分享的程序员宝妹儿。

本篇全面深入 Undo log 回滚日志的基础概念、两大作用、物理结构、工作原理、以及其在事务中的流程等。

PS.

刚结束的 Binlog 系列,宝子们的反馈还不错,例如:例如:binlog从基础到精通系列,图解bin log、redo log及undo log区别等,宝妹儿已将内容更新到《MySQL 大厂高频面试题大全》PDF了,方便系统学习、面试通关。

《MySQL 大厂高频面试题大全》PDF,已收录100+道真题,一共 78 页,近 30000 + 字,文末自取。

吃透它,足以应付MySQL面试。

01

Undo log 的基础知识

上一篇介绍了:

Undo log 的概念Undo log 的两大作用Undo log 的存储机制Undo log 的工作原理

点击蓝字回顾:图解MySQL Undo log的存储机制及工作原理,3分钟精通!

02

Undo log 的作用

Undo log 的两大作用分别是提供数据回滚、多版本控制 MVCC。

提供数据回滚(原子性)

事务具有 ACID 特性,其中,"A"代表事务的原子性(Atomicity)。

即:事务中的所有操作要么全部成功执行,要么全部回滚。

undo log(回滚日志)的回滚操作是实现原子性的关键,它保证了事务的 ACID 特性中的原子性。

undo log 是一种用于撤销回退的日志,在事务没提交之前,MySQL 会先记录更新前的数据到 undo log 日志文件里面,当事务回滚时或数据库崩溃时,可以利用 Undo Log 进行数据回滚。

多个行版本控制 MVCC

undo log 还有一个作用,通过 ReadView + undo log 实现 MVCC。

当用户读取某个记录时,如果这个记录已被其它的事务所占用,通过 Undo Log 读取之前的行版本信息,当前事务就可以实现非锁定读取。

undo log 为每条记录保存多份历史数据,MySQL 在执行快照读(普通 select 语句)的时候,会根据事务的 Read View 里的信息,顺着 undo log 的版本链找到满足其可见性的记录。

一条记录的每一次更新操作产生的 undo log 格式都有一个 roll_pointer 指针和一个 trx_id 事务id:

通过 trx_id 可以知道该记录是被哪个事务修改的;通过 roll_pointer 指针可以将这些 undo log 串成一个链表,这个链表就被称为版本链。

版本链如下图:

03

Undo log 的物理结构

Undo log 的物理结构,由上到下分别为:

回滚表空间回滚段 (undo log segment)undo log slotpage

Undo log 由 128 个回滚段(Rollback segment)构成。

其中,32 个回滚段用于系统的临时表空间,96 个回滚段用于事务。

slot 0 ,预留给系统表空间;slot 1- 32,预留给临时表空间,每次数据库重启的时候,都会重建临时表空间;slot 33-127,如果有独立表空间,则预留给UNDO独立表空间;如果没有,则预留给系统表空间。

回滚段中除去 32 个提供给临时表事务使用,剩下的 128-32=96个回滚段,可执行 96*1024 个并发事务操作,每个事务占用一个 undo segment slot。

如果事务中有临时表事务,在临时表空间中的 undo segment slot 会再占用一个 undo segment slot,即占用2个 undo segment slot。如果错误日志中有 Cannot find a free slot for an undo log,说明并发的事务太多了,需要考虑是否分流业务。

每个回滚段对应一个 segment header page,在这个 page 中又划分了 1024 个 slot,每个 slot 又对应到一个 undo log 对象。

独立表空间的 space id 是从 1 开始的,0 被预留在 ibdata 中,space id 是连续分配、并且不能断档的。

回滚段

这里再重点聊下回滚段。

回滚段(Rollback Segment)是存储 Undo log 的数据结构,由多个回滚段组成,每个回滚段有多个 undo log slot,负责存储特定范围的事务 Undo log 。

回滚段采用轮询调度的方式来分配使用,如果设置了独立表空间,就不会使用系统表空间回滚段中 undo segment,而是使用独立表空间,同时,如果回滚段正在 Truncate 操作,则不分配。

InnoDB 在 undo tablespace 中使用回滚段来组织 undo log,以及维护 undo log 的并发写入和持久化。

通过 Rollback Segment Header 来管理回滚段,Rollback Segment Header 的结构:

回滚段有 update_undo、insert_undo 两种类型。

update_undo:

只用于事务内的 update 和 delete 语句。加入到其对应 rollback segment 的 history list 数据页列表上,history list 长度加1。该 log 需要提供 MVCC 机制,因此不能在事务提交时就进行删除。提交时放入 undo log 链表,等待 purge 线程进行清除。

insert_undo:

只用于事务内的 insert 语句。新插入的记录产生的 undo 不会被任何查询语句所引用,因此可以直接释放 undo,此处 undo log 不会累加到 history list 上。insert 操作的记录只对事务本身可见,因此,该 undo log 不需要进行 purge 操作,在事务提交后就直接删除。

delete 和 update 操作最终都是由 purge 来完成的。

innodb_purge_batch_size:全局动态参数,默认值为 300,用来设置每次 purge 操作需要清理的 undo page 数量。innodb_max_purge_lag:全局动态参数,用来控制 history list 的长度,若大于该参数时,其会延缓 DML 的操作。innodb_max_purge_lag_delay:全局动态参数,用来控制 DML 操作每行数据的最大延缓时间,单位为毫秒。

如果需要对回滚段做配置,可以调整如下几个参数:

innodb_undo_log_truncate

InnoDB 的 purge 线程,根据 innodb_undo_log_truncate 设置开启或关闭、innodb_max_undo_log_size 的参数值,以及 truncate 的频率来进行空间回收和 undo file 的重新初始化。该参数生效的前提是,已设置独立表空间且独立表空间个数大于等于 2 个。

innodb_max_undo_log_size

控制最大的 undo tablespace 文件大小,当启动了 innodb_undo_log_truncate 、且 undo tablespace 超过 innodb_max_undo_log_size 阀值时,才会去尝试 truncate 。该值默认大小为 1G,truncate 后的大小默认为 10M。

innodb_undo_tablespaces

设置 undo 独立表空间个数,范围为 0-128, 默认为 0,0 表示不开启独立 undo 表空间、且 undo日志存储在 ibdata 文件中。该参数只能在最开始初始化 MySQL 实例的时候指定,如果实例已创建,这个参数是不能变动的,如果在数据库配置文件 .cnf 中指定 innodb_undo_tablespaces 的个数大于实例创建时的指定个数,就会启动失败,并提示该参数设置错误。

innodb_undo_directory

设置 rollback segment 文件所在位置的路径,这意味着 rollback segment 可以存放在共享表空间以外的位置,即可以设置为独立表空间。该参数的默认值为“.”,标识当前InnoDB存储引擎的位置的目录。

innodb_undo_log

用来设置 rollback segment 的个数。默认值为128个。

04

Undo log 在事务中的流程

事务在 undo log segment 分配、且写入 undo log 的同时,也会产生 redo log。

当事务提交时(commit):

将 undo log 放入列表中,以供之后的 purge(pai rui chi) 线程使用;判断 undo log 所在的页能否重用,如果可以重用,则分配给下个事务使用;事务提交后,不能马上删除 undo log 及 undo log 所在的页,这是因为还有其他事务需要通过 undo log 来得到行记录之前的版本,故事务提交将 undo log 放入一个链表中,是否可以最终删除 undo log 及 undo log 所在页由 purge 线程来判断。

当事务提交时,先将 undo log 放入链表中,判断 undo 页的使用空间是否小于 3/4(表示 undo log 可否被重用)。

之后新的undo log 记录在当前的 undo log 的后面,由于存放 undo log 的列表是以记录进行组织的,undo log 可能存放着不同事务的 undo log。

因此,prege 操作需要设计磁盘的离散读取操作,这个过程很缓慢,可以通过设置 purge 线程的个数来提升回收速度。

05

总结

通过本文,我们掌握了 Undo log 回滚日志的概念、工作原理、物理结构以及在事务中的流程等,希望能帮助大家深入理解、正确应用 Undo log 。

建议收藏备用,划走就找不到啦。

如果有用,请顺手给宝妹儿【关注+点赞】支持下哦,拜谢。

PS.

本文已收录于宝妹儿精编的 2023版《MySQL 大厂高频面试题大全》PDF。

《MySQL 大厂高频面试题大全》一共78页,34000字,图文并茂,长期持续更新。

吃透它,足以应对 MySQL 面试。

标签: #mysql必知必会pdf英语版下载