MySQL的redo log 、binlog和undolog

目录

  • redo log部分
    • 1、为什么需要redo log?
    • 2、redo log的写入机制
    • 3、Redo Log的生成和释放
    • 4、 Redo log工作过程
    • 5、疑问:事务提交后直接刷盘不就好了,为什么还要记录一份数据到redo log中呢,redo log也得刷盘后才能保证事务成功?
  • binlog部分
    • 1、redo log 和 binlog的区别
    • 2、一条更新语句的执行过程(redo log和binlog的配合)
    • 3、prepare和binlog是如何保证一致性的?
  • 最佳实践部分
  • undo log部分
    • 1、Undo Log介绍
    • 2、Undo Log作用
      • 2.1 实现事务的原子性
      • 2.2 实现多版本并发控制(MVCC)
  • 参考链接

redo log部分

1、为什么需要redo log?

  1. redo log 最主要的作用就是用于数据库异常宕机的恢复工作
  2. 假如数据库永远不会发生异常宕机,那么其实根本不需要redo log,因为innodb中有线程不断的做把脏页刷新到磁盘的工作,数据库如果一直不宕机,就不会出现问题。

2、redo log的写入机制

redo log是一个环,大小是固定的,文件个数和大小是可以配置的。其中有两个指针,write和checkpoint,分别对应可以写入的位置,和已经刷新到磁盘的位置。

当write追上了checkpoint,说明已经没有空闲的位置可以写入了,就需要刷新一下,保证有位置可以写入。
MySQL的redo log 、binlog和undolog_第1张图片
如图所示:

write pos是当前记录的位置,一边写一边后移,写到最后一个文件末尾后就回到 0 号文件开头;

checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件;

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

3、Redo Log的生成和释放

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

4、 Redo log工作过程

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

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

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

对于从磁盘中读取和写入数据的操作,叫做磁盘IO,分两种情况:

  1. 随机IO就是读写的内容分散在磁盘的不同位置,需要来回查找所以效率低;

  2. 顺序IO就是读写的内容集中存储在磁盘的一块,从前到后依次读取,免去了查找的过程,所以效率高。

  • 机械磁盘的顺序IO和随机IO的性能差异巨大。

  • 顺序IO时缓存命中率高,节省寻道时间。

  • 随机IO不停寻址,缓存失效。

应用:

  • 复制文件夹:复制文件夹的时候,如果包含许多小文件,复制速度很慢。为了提高复制速度,可以先打一个包,打包把文件夹变成一个大文件。再复制的时候,变成顺序IO

  • 数据库事务:数据库事务在实现的时候,要保证数据落盘成功才能返回。落盘是指落盘到自己的事务日志文件里就返回成功,而不是直接写入到数据库表文件里。原因还是磁盘读写性能问题,事务只要落盘成功就可以,写到哪里不重要。写到数据文件就变成随机IO了。如果写到一个日志文件中,就是顺序IO

  • MySql的B+树:无论是顺序IO还是随机IO,增加每次IO的单位,性能都会上涨。B+树节点更大,IO起来磁盘工作更舒服。

binlog部分

1、redo log 和 binlog的区别

  1. redo log是 innodb存储引擎特有的;binlog是server层,属于共有的
  2. redo log是物理日志,记录在某个数据页的修改;binlog是逻辑日志
  3. redo log是一个环,循环写;binlog是追加写,不会覆盖以前的日志
  4. redo log用于异常重启恢复;binlog用于备份

2、一条更新语句的执行过程(redo log和binlog的配合)

  1. 执行器调用引擎接口写入新数据
  2. 引擎把更新操作记录到 redo log中,此时redo log为prepare状态
  3. 执行器生成这个操作的binlog,并写入磁盘
  4. 执行器调用引擎的事务提交接口,引擎把redo log的状态改为commit

MySQL的redo log 、binlog和undolog_第3张图片

3、prepare和binlog是如何保证一致性的?

  1. prepare阶段
  2. binlog写入阶段
  3. commit阶段

在2阶段之前崩溃时:

  • 重启恢复:发现没有commit,回滚
  • 备份恢复:没有binlog

保持了一致性

在3阶段之前崩溃时:

  • 重启恢复:虽没有commit,但是binlog有,并且一致,所以恢复
  • 备份恢复:有binlog

保持了一致性

最佳实践部分

  1. innodb_flush_log_at_trx_commit 参数建议设置为1,每次更新操作,redo log都会刷新到磁盘
  2. sync_binlog 参数建议设置为1,每次更新操做,binlog会刷新到磁盘

undo log部分

1、Undo Log介绍

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

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

Undo Log产生和销毁:Undo Log在事务开始前产生;事务在提交时,并不会立刻删除UndoLog,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存储:

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     |
+--------------------------+-------+

2、Undo Log作用

2.1 实现事务的原子性

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

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

Undo Log 在MySQL InnoDB存储引擎中用来实现多版本并发控制。事务未提交之前,Undo Log保存了未提交之前的版本数据,Undo Log 中的数据可作为数据旧版本快照供其他并发事务进行快照读。
MySQL的redo log 、binlog和undolog_第4张图片
事务A手动开启事务,执行更新操作,首先会把更新命中的数据备份到Undo Buffer中。

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

参考链接

  • https://www.jianshu.com/p/e441d398d14d
  • https://www.csdn.net/tags/OtDagg4sMDM2OTctYmxvZwO0O0OO0O0O.html
  • https://blog.csdn.net/u014635079/article/details/121925506

你可能感兴趣的:(mysql,java,后端,mysql)