赞
踩
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。