【MySQL04】【 redo 日志】

一、前言

最近在读《MySQL 是怎样运行的》、《MySQL技术内幕 InnoDB存储引擎 》,后续会随机将书中部分内容记录下来作为学习笔记,部分内容经过个人删改,因此可能存在错误,如想详细了解相关内容强烈推荐阅读相关书籍


系列文章内容目录:

  1. 【MySQL00】【 杂七杂八】
  2. 【MySQL01】【 Explain 命令详解】
  3. 【MySQL02】【 InnoDB 记录存储结构】
  4. 【MySQL03】【 Buffer Pool】
  5. 【MySQL04】【 redo 日志】
  6. 【MySQL05】【 undo 日志】
  7. 【MySQL06】【MVCC】
  8. 【MySQL07】【锁】
  9. 【MySQL08】【死锁】

二、redo 日志

事务四大特性 :ACID (原子性、一致性、隔离性、持久性)

  1. 原子性 (atomicity):事务要么成功要么失败,不存在中间状态
  2. 一致性 (consistency):事务将DB 从一种状态转变为另一种一直的状态,在事务开始前和结束后,DB的完整性约束没有被破坏。
  3. 隔离性 (isolation):每个读写事务的对象对其他事物的操作对象能相互分离,即该事务提交前对其他事务都不可见,通常使用锁来实现
  4. 持久性 (durability):事务一旦提交,其结果就是永久性的

其中 D (持久性) 的是由 redo 日志来实现的, redo 日志由两部分组成:一是内存中的重做日志缓冲(redo log buffer),是易失的;而是redo 日志文件(redo log file),是持久的。


InnoDB 是以页为单位来管理存储空间的,我们进行的增删改查操作本质上都是对页的操作,而前面【MySQL03】【 Buffer Pool】 中提到过,InnoDB 在真正访问页面时,会先判断页在 Buffer Pool 中是否存在,如果存在则直接操作 Buffer Pool 中的页,否则将页从磁盘读取到 Buffer Pool 中再操作。而 Buffer Pool 中的页在被修改后并不会立刻刷新到磁盘,此时就会造成 Buffer Pool 中的页与磁盘页的数据并不相同,即脏页。而如果在一个事务提交后,修改数据写到 Buffer Pool 中但是并未刷盘,如果此时系统宕机内存数据全部丢失则会造成数据的不一致。

一个简单的做法是在事务提交前将所有的页面都刷新到磁盘,不过该方案存在如下问题:

  1. 刷新一个完整的页面太浪费了,有时候仅仅修改了页面的一个字节也需要将整个页刷新到磁盘。
  2. 随机IO刷新效率太低。一个事务可能包含很多语句,即使一个语句也可能修改很多页面,并且这些页面可能并不相邻,在将这些页面刷新到磁盘的时候需进行很对随机IO。

因为上述问题,InnoDB 并不是在事务提交时将所有页刷新到磁盘,而是将修改的内容记录下来,在合适的时机刷新到磁盘中。(记录的并不是全量内容,而是增量内容,因此需要 double write 来保证写入的可靠性。),比如某个事务将系统表空间第100号页面中偏移量为 1000 处的变量值从 1 改成2,只需要记录:

将系统表空间第100号页面中偏移量为 1000 处的变量值更新为2

当事务提交后就会将上述内容刷新到磁盘,即使之后系统崩溃了重启之后按照记录内容重新更新数据页即可。上述内容被称为重做日志(redo log),使用重做日志有如下好处:

  1. redo 日志占用空间非常小:在存储表空间ID、页号、偏移量以及需要更新的值时需要的存储空间很小。
  2. redo 日志是顺序写入磁盘的:在事务执行过程中每执行一条语句,就可能产生若干个 redo 日志,这些日志是按照产生的顺序写入磁盘的,即顺序IO。

所以 InnoDB 通过 Force Log at Commit 机制实现事务的持久性,即当事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的提交操作完成才算完成。这里的日志指的是 重做日志,其由两部分组成,即 redo log 和 undo log。 redo log 用来保证事务的持久性; undo log 用来帮助事务回滚以及 MVCC 的功能。redo log 基本都是顺序写, 在 DB运行时不需要对 redo log 文件进行读取操作,而 undo log 是需要进行随机读写。

为了确保每次日志都写入重做日志文件,在每次将重做日志缓冲写入 redo log 后, InnoDB 都需要调用一次 fsync 来刷新文件缓冲区数据到磁盘中。InnoDB 允许设置非持久性的情况,即当事务提交时,日志不写入重做日志文件,而是等待一个时间周期后再执行 fsync 操作,借此可以提高DB性能,但是宕机后可能会存在最新数据丢失。

1. redo 日志格式

在这里插入图片描述

具体字段如下:

字段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫吻鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值