zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

MYSQL 8 UNDO 表空间 你了解多少

2023-02-18 16:23:53 时间

UNDO LOG 的主要目的是完成事务回滚和MVCC 多版本控制中的读取过去事务的问题。

UNLOG 这里有三个层次的问题

1 undo log 存在于undo log 的日志段中

2 undo log 的日志段 存在于undo log的回滚段中

3 unlog log 的回滚段存在于undo 表空间和 全局临时表空间中

这里提到为什么有两个位置来存储UNDO LOG

1 UNDO 在全局临时表空间存储的事务是不需要回滚的,主要这里存储的是数据库临时表中产生的事务,所以这部分UNDO 不需要回滚,也没有对应的REDO LOG 在系统CRASH 后是不需要 recovery 的。

2 存在UNDO 表空间的信息,这部分是需要单独存储在UNDO 表空间中的

这里每个UNDO 表空间 和临时表空间最大支持 128个回滚段,通过 innodb_rollback_segments 来定义回滚段的数量。同时根据innodb page size 的大小来决定回滚段的槽位数。

以我们默认的16KB 一个页面,一个回滚段的槽位是1024个, 同时支持四种类型的操作进入回滚槽位中

INSERT (UPDATE AND DELETE) --- 非临时事务

INSERT (UPDATE AND DELETE) --- 临时事务

在事务执行的过程中,UNDO LOG 是数据库限制并发事务数的一个关键指标,如果并发的事务的数字超过当前UNDO LOG 的限制,则会导致事务运行失败。

如何计算当前UNDO LOG 的对于并发事务的限制可以通过下方的计算公式进行计算。

按照默认来计算,默认的INNODB_PAGE_SIZE的尺寸,16384 / 16 * 128 * undo 表空间个数,默认为 2。

16384 /16 * 128 * 2 = 262,144 ,所以一般来说并发事务如果不超过这个数字是不会出现故障的,但主要注意的是,如果事务中包含了 insert update delete 则这个数字要在除以 2

我们按照正常事务的情况,整体并发的事务数字在 131072, 所以如果你并发的事务比较多,发生过因为这个并发事务数导致的事务无法进行的问题,则可以添加 undo tablespace.

关于UNDO TABLESPACE 在MYSQL 8 和 MYSQL 5.7 有一些区别,首先mysql 5.7 的 undo log 默认是3个, MYSQL 8 默认是2个 innodb_undo_001 和 innodb_undo_002, 在之前 MYSQL 5.7 之前UNDO LOG 是无法在系统运行的时间进行添加的,而在8.014 版本后,MYSQL 8 是可以动态的添加UNDO LOG TABLESPACE

这里就动态的添加了一个UNDO 的table space。另外需要注意默认的undo log tablespace 是会建立在当前的datadir 目录下,整体的undo log 的顺序是这样的从上到下

1 innodb_undo_directory

2 innodb_data_home_dir

3 innodb_directories

4 datadir

这五个部分一般不设置的情况下,都是按照datadir的目录进行设置的,同时新添加的undo log的名字的结尾必须是 ibu ,因为系统会在文件目录中搜索以ibu为结尾的文件作为undo log 添加的表空间。

下面的语句可以将你当前的 undo table space 进行一个搜寻,展示当前有多少undo log 的 表空间

SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE LIKE 'UNDO LOG';

除此以外,undo log table space 是需要进行回收的,通过回收保证下一次的使用,这里就需要不断的对UNOD LOG 的空间进行回收。undo 表空间也是轮训使用的,则在这个UNDO 表空间不在被使用的情况下,对表空间进行 innodb_undo_log_truncate 的操作,而进行这个操作是需要一个阀值的,阀值就是 innodb_max_undo_log_size ,通过这个值来控制对undo 表空间进行truncate 的操作,默认值是 1024MB。

而innodb_max_undo_log_size 是对undo log 进行truncate 操作的阀值,我们怎么对undo log 的工作状态进行监控。

SET GLOBAL innodb_monitor_enable=module_undo;

SET GLOBAL innodb_monitor_enable=module_purge;

SELECT NAME,SUBSYSTEM,COUNT,STATUS,COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%truncate%';

通过上面的语句可以查看当前的 undo log truncate的情况,如 已经进行了多少次的 truncate ,以及工作的时间等等 。

同时MYSQL 8 的 UNDO LOG 的表空间可以进行卸载的工作,将undo log 表空间置为inactive ,然后在进行卸载。

说完上面的问题,我们说说UNDO LOG 的逻辑组织模式

这里每个事务在修改行记录的时候,都会产生UNDO 记录,下面是一个UNLOG LOG 存储的逻辑结构,这里在每个页面的页头都有 undo log header 来记录必要的控制信息,产生UNDO LOG 的事务的ID 会按照执行的顺序被记录在页头中 TRXID , 同时每个事务可能操作多条记录,那么多条记录的顺序在 Trx No中体现,delete mark 主要标记相关的信息在UNDO LOG 中可以被PURGE ,避免无效的大量扫描工作。Next undo log 和 Prev undo log 是记录前后UNDO LOG 的位置

如果不同的事务修改记录和索引的情况下,不同的历史版本就会被产生,同时通过rollptr 来将这些不同历史时期的数据进行连接。以供在事务存续期间多版本控制中,推送不同的版本的数据给当时的读取这行的事务。

上图例子中的事务I 插入了一条记录,而事务J 将这条记录修中的字段a 修改为 B 后面 K 事务将这个字段修值修改为 C ,通过rollptr可以看到这行数据库在时间线上的被不同事务修改的过程。

参考文字:

https://www.alibabacloud.com/blog/an-in-depth-analysis-of-undo-logs-in-innodb_598966