5.1 Undo Log

用于保证事务ACID中的原子性。

事务没提交时,会将记录更新前的数据记录到undo log日志文件中。

  • 插入:记录主键值
  • 删除:记录这条记录全部内容
  • 更新:记录这条记录旧值

一条记录的每一次更新操作产生的undo log格式都有一个roll_pointer和trx_id指针,分别用于将undo log串成链表和记录被哪个事务所修改。

所以undo log还可以和ReadView配合实现MVCC。

作用:

  • 实现事务回滚,保障事务的原子性。事务处理过程中,如果出现了错误或者用户执 行了 ROLLBACK 语句,MySQL 可以利用 undo log 中的历史数据将数据恢复到事务开始之前的状态。
  • 实现 MVCC(多版本并发控制)关键因素之一。MVCC 是通过 ReadView + undo log 实现的。undo log 为每条记录保存多份历史数据,MySQL 在执行快照读(普通 select 语句)的时候,会根据事务的 Read View 里的信息,顺着 undo log 的版本链找到满足其可见性的记录。

5.2 Redo Log

redo log用于保证ACID中的持久性。

由于更新数据会先写入Buffer Pool,而内存是不可靠的,所以为了防止断电导致数据丢失,InnoDB会先更新内存,然后将本次对这个页的修改以redo log的形式记录,后续在适当的时候,后台线程再将Buffer Pool中的脏页刷到磁盘中,这就是WAL(Write-Ahead Logging)技术。

WAL 技术指的是, MySQL 的写操作并不是立刻写到磁盘上,而是先写日志,然后在合适的时间再写到磁盘上

redo log是物理日志,记录某个数据页做了什么修改,每执行一个事务就会产生这样一条或者多条物理日志,事务提交时,只需要将redo log持久化到磁盘即可,不需要等待buffer pool中的脏页持久化。

这样即使系统崩溃,虽然脏页没有持久化,但是MySQL可以根据redo log的内容,将数据恢复到最新状态。

被修改的Undo页面,需要记录对应的redo log。在内存修改该 Undo 页面后,需要记录对应的 redo log

  • redo log 和 undo log区别:
    • 两种日志都是存储引擎日志
    • redo log 记录了此次事务「完成后」的状态,记录的是更新之后的值。
    • undo log 记录了此次事务「开始前」的状态,记录的是更新之前的值。

写入 redo log 的方式使用了追加操作, 所以磁盘操作是顺序写,而写入数据需要先找到写入位置,然后才写到磁盘,所以磁盘操作是随机写

磁盘的「顺序写 」比「随机写」 高效的多,因此 redo log 写入磁盘的开销更小。

作用:

  • 实现事务的持久性,让 MySQL 有 crash-safe 的能力,能够保证 MySQL 在任何时间段突然崩溃,重启后之前已提交的记录都不会丢失;
  • 将写操作从「随机写」变成了「顺序写」,提升 MySQL 写入磁盘的性能。

5.2.1 产生的redo log是直接写入磁盘吗?

不是,redo log有自己的缓存redo log buffer,每产生一条redo log时,会先写入redo log buffer。

刷盘时机:

  • MySQL正常关闭时;
  • 当redo log buffer中写入量大于redo log buffer内存空间(16MB)的一半时;
  • InnoDB的后台线程每隔1s,将redo log buffer持久化到磁盘;
  • 每次事务提交时,都将缓存在redo log buffer中的redo log直接持久化到磁盘。

redo log Group:

InnoDB存储引擎有一个重做日志文件组,有两个redo log文件组成,每个文件大小固定且一致,以循环写的方式工作。

  • write pos:表示当前记录写到的位置;
  • check point:表示当前要擦除的位置,因为buffer pool中的脏页已经刷新到了磁盘;
  • 如果write pos追上了check point,此时redo log文件满,MySQL不能执行新的更新操作,会被阻塞,并将Buffer Pool中脏页数据刷到磁盘,然后标记可以擦除的记录。

5.3 Bin Log

5.4 两阶段提交

5.5 磁盘IO高怎么办