当前位置: 代码迷 >> 综合 >> 数据库:mysql:undo log
  详细解决方案

数据库:mysql:undo log

热度:88   发布时间:2024-02-06 23:58:07.0

一、定义

用来进行事务回滚操作所需要的文件。

二、作用

  • 对事务进行回滚操作
  • MVCC控制,当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现一致性非锁定读取。

三、存放位置

在共享表空间内的undo log段。

四、注意

  • undo是逻辑日志,因此只是将数据库逻辑地恢复到原来的样子。所有修改都被逻辑地取消了,但是数据结构和页本身在回滚之后可能大不相同。
  • undo log会产生redo log,也就是undo log的产生会伴随着redo log的产生,这是因为undo log也需要持久性的保护。

五、undo存储管理

InnoDB存储引擎对undo的管理同样采用段的方式。但是这个段和之前介绍的段有所不同。首先InnoDB存储引擎有rollback segment,每个回滚段种记录了1024个undo log segment,而在每个undo log segment段中进行undo页的申请。

需要特别注意的是,事务在undo log segment分配页并写入undo log的这个过程同样需要写入重做日志。当事务提交时,InnoDB存储引擎会做以下两件事情:

  • 将undo log放入列表中,以供之后的purge操作
  • 判断undo log所在的页是否可以重用,若可以分配给下个事务使用

事务提交后并不能马上删除undo log及undo log所在的页。这是因为可能还有其他事务需要通过undo log来得到行记录之前的版本。故事务提交时将undo log放入一个链表中,是否可以最终删除undo log及undo log所在页由purge线程来判断。

1. undo 设置

mysql> show variables like 'innodb_undo%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_undo_directory    | ./    |
| innodb_undo_log_truncate | OFF   |
| innodb_undo_logs         | 128   |
| innodb_undo_tablespaces  | 0     |
+--------------------------+-------+mysql> show variables like 'datadir%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
  • innodb_undo_directory:用于设置rollback segment文件所在的路径。这意味着rollback segment可以存放在共享表空间以外的位置,即可以设置为独立表空间。
  • innodb_undo_logs:用来设置rollback segment的个数,默认值为128。
  • innodb_undo_tablespaces:用来设置构成rollback segment文件的数量,这样rollback segment可以较为平均地分布在多个文件中。

六、undo重用

若为每一个事务分配一个单独的undo页会非常浪费存储空间,特别是对于OLTP的应用类型。因为在事务提交时,可能并不能马上释放页。假设某应用的删除和更新操作的TPS(transaction per second)为1000,为每个事务分配一个undo页,那么一分钟就需要1000*60个页,大约需要的存储空间为1GB。若每秒的purge页的数量为20,这样的设计对磁盘空间有着相当高的要求。因此,在InnoDB存储引擎的设计中对undo页可以进行重用。

当事务提交时,首先将undo log放入链表中,然后判断undo页的使用空间是否小于3/4,若是则表示该undo页可以被重用,之后新的undo log记录在当前undo log的后面。

//查看undo log 数量
mysql> SHOW ENGINE INNODB STATUS;
......
------------
TRANSACTIONS
------------
Trx id counter 13090
Purge done for trx's n:o < 13087 undo n:o < 0 state: running but idle
History list length 49
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421304033991416, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421304033990496, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
--------
.....

History list length 49 表示undo log 数量

七、undo log 格式

1. undo log 分类

在InnoDB存储引擎中,undo log分为:

  • insert undo log: 是指在insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(这是事务隔离性的要求),故该undo log可以在事务提交后直接删除。不需要进行purge操作。
  • update undo log:记录的是对delete和update操作产生的undo log。该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。

在这里插入图片描述

八、undo log 回收

1. 回收机制

总的来说:InnoDB存储引擎这种通过purge线程先从history list中找undo log,然后再从undo page中找undo log。
在这里插入图片描述
在执行purge的过程中,InnoDB存储引擎首先从history list中找到第一个需要被清理的记录,这里为trx1,清理之后InnoDB存储引擎会在trx1的undo log所在的页中继续寻找是否存在可以被清理的记录,这里会找到事务trx3,接着找到trx5,但是发现trx5被其他事务所引用而不能清理,故去再次去history list中查找,发现这时最尾端的记录为trx2,接着找到trx2所在的页,然后依次再把事务trx6、trx4的记录进行清理。由于undo page2中所有的页都被清理了,因此该undo page可以被重用。

2. 优点

避免大量的随机读取操作,从而提高purge的效率。

3. 回收相关设置

//每次purge操作需要清理的undo page数量
mysql> show variables like 'innodb_purge_batch_size';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| innodb_purge_batch_size | 300   |
+-------------------------+-------+//用来控制history list的长度,若长度大于该参数时,其会“延缓”DML的操作。该参数默认值为0,表示不对history list做任何限制。
mysql> show variables like 'innodb_max_purge_lag';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_max_purge_lag | 0     |
+----------------------+-------+//当innodb_max_purge_lag 大于0时,就会延缓DML的操作,其延缓的算法为:delay=((length(history_list)-innodb_max_purge_lag)*10)-5
//来控制delay的最大毫秒数。也就是当上述计算得到的delay值大于该参数时,将delay设置为innodb_max_purge_lag_delay,避免由于purge操作缓慢导致其他SQL线程出现无限制的等待。
mysql> show variables like 'innodb_max_purge_lag_delay';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| innodb_max_purge_lag_delay | 0     |
+----------------------------+-------+
  相关解决方案