MySQL中的Undo Log、Redo Log

痛定思痛。 2023-01-16 12:24 117阅读 0赞

Undo log

Undo Log介绍

Undo:意为撤销或取消,以撤销操作为目的,将数据返回到某个状态的操作(有点类似ctrl+z)。

Undo Log:数据库事务开始之前,会将要修改的记录存放到 Undo 日志里,当事务回滚时或者数
据库崩溃时,可以利用 Undo 日志,撤销未提交事务对数据库产生的影响。

Undo Log产生和销毁:Undo Log在事务开始前产生;事务在提交时,并不会立刻删除Undo
Log,innodb会将该事务对应的undo log放入到删除列表中,后面会通过后台线程purge thread进
行回收处理。Undo Log属于逻辑日志,记录一个变化过程。例如执行一个delete语句,Undo Log会记
录一个insert语句;执行一个update语句,Undo Log会记录一个相反的update语句。

Undo Log存储:Undo Log采用段的方式管理和记录。在innodb数据文件中包含一种rollback
segment回滚段,内部包含1024个Undo Log segment。

可以通过下面一组参数来控制Undo log存
储:

  1. mysql> show variables like '%innodb_undo%';
  2. +--------------------------+-------+
  3. | Variable_name | Value |
  4. +--------------------------+-------+
  5. | innodb_undo_directory | ./ |
  6. | innodb_undo_log_truncate | OFF |
  7. | innodb_undo_logs | 128 |
  8. | innodb_undo_tablespaces | 0 |
  9. +--------------------------+-------+

Undo Log作用

实现事务的原子性

Undo Log 是为了实现事务的原子性而出现的产物。事务处理过程中,如果出现了错误或者用户执
行了 ROLLBACK 语句,MySQL 可以利用 Undo Log 中的备份将数据恢复到事务开始之前的状态。

实现多版本并发控制(MVCC)

Undo Log 在MySQL InnoDB存储引擎中用来实现多版本并发控制。事务未提交之前,Undo Log
保存了未提交之前的版本数据,Undo Log 中的数据可作为数据旧版本快照供其他并发事务进行快
照读。

在这里插入图片描述

事务A手动开启事务,执行更新操作,首先会把更新命中的数据备份到Undo Buffer中。

事务B手动开启事务,执行查询操作,会读取Undo日志数据返回,进行快照读,这样可以实现事务隔离级别的读已提交。

Redo log

Redo Log介绍

Redo:顾名思义就是重做。以恢复操作为目的,在数据库发生意外时重现操作(类似ctrl+y)。

Redo Log:指事务中修改的任何数据,将最新的数据备份存储的位置(Redo Log),被称为重做
日志。

Redo Log的生成和释放:随着事务操作的执行,就会生成Redo Log,在事务提交时会将产生
Redo Log写入Log Buffer,并不是随着事务的提交就立刻写入磁盘文件。等事务操作的脏页写入
到磁盘之后,Redo Log的使命也就完成了,Redo Log占用的空间就可以重用(被覆盖写入)。

Redo Log工作原理

Redo Log 是为了实现事务的持久性而出现的产物。防止在发生故障的时间点,尚有脏页未写入表
的IBD文件中,在重启MySQL服务的时候,根据Redo Log进行重做,从而达到事务的未入磁盘
数据进行持久化这一特性。

在这里插入图片描述

疑问:事务提交后直接刷盘不就好了,为什么还要记录一份数据到redo log中呢,redo log也得刷盘后才能保证事务成功?

事务提交后表数据的刷盘与redo log数据的刷盘同样都是IO操作,表数据的刷盘是随机IO,而redo log数据的刷盘是顺序IO,顺序IO比随机IO更快。

Redo Log写入机制

Redo Log文件内容是以顺序循环的方式写入文件,写满时则回溯到第一个文件,进行覆盖写。

在这里插入图片描述

如图所示:

  • write pos是当前记录的位置,一边写一边后移,写到最后一个文件末尾后就回到 0 号文件开
    头;
  • checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数
    据文件;

write pos和checkpoint之间还空着的部分,可以用来记录新的操作。如果write pos追上
checkpoint,表示写满,这时候不能再执行新的更新,得停下来先擦掉一些记录,把checkpoint
推进一下。

Redo Log相关配置参数

每个InnoDB存储引擎至少有1个重做日志文件组(group),每个文件组至少有2个重做日志文
件,默认为ib_logfile0和ib_logfile1。可以通过下面一组参数控制Redo Log存储:

  1. mysql> show variables like '%innodb_log%';
  2. +-----------------------------+----------+
  3. | Variable_name | Value |
  4. +-----------------------------+----------+
  5. | innodb_log_buffer_size | 16777216 |
  6. | innodb_log_checksums | ON |
  7. | innodb_log_compressed_pages | ON |
  8. | innodb_log_file_size | 50331648 |
  9. | innodb_log_files_in_group | 2 |
  10. | innodb_log_group_home_dir | ./ |
  11. | innodb_log_write_ahead_size | 8192 |
  12. +-----------------------------+----------+

在这里插入图片描述

Redo Buffer持久化到Redo Log的策略,可通过innodb_flush_log_at_trx_commit设置:

  • 0:每秒提交 Redo buffer ->OS cache -> flush cache to disk,可能丢失一秒内的事务数
    据。由后台Master线程每隔 1秒执行一次操作。
  • 1(默认值):每次事务提交执行 Redo Buffer -> OS cache -> flush cache to disk,最安
    全,性能最差的方式。
  • 2:每次事务提交执行 Redo Buffer -> OS cache,然后由后台Master线程再每隔1秒执行OS
    cache -> flush cache to disk 的操作。

一般建议选择取值2,因为MySQL 挂了数据没有损失,整个服务器挂了才会损失1秒的事务提交数
据。

  1. mysql> show variables like '%Innodb_flush_log_at_trx_commit%';
  2. +--------------------------------+-------+
  3. | Variable_name | Value |
  4. +--------------------------------+-------+
  5. | innodb_flush_log_at_trx_commit | 1 |
  6. +--------------------------------+-------+

发表评论

表情:
评论列表 (有 0 条评论,117人围观)

还没有评论,来说两句吧...

相关阅读

    相关 binlog,undo log,redo log

    什么是binlog binlog日志用于记录所有更新且提交了数据或者已经潜在更新提交了数据(例如,没有匹配任何行的一个DELETE)的所有语句。语句以“事件”的

    相关 453-MySQL(MVCC和undo log)

    我们一般工作在事务的中间两级隔离级别 2、TRANSACTION\_READ\_COMMITTED。已提交读。说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚