一、背景介绍
- 持久性要求: 对于已提交的事务,即使系统发生崩溃,其对数据库的更改也不能丢失。
- 问题:
- 在事务提交前将所有修改的页面刷新到磁盘浪费资源。
- 随机IO导致刷新速度慢。
- 解决方案:
- 【数据副本】记录事务执行过程中所做的修改,称为 Redo 日志。
- 【顺序写入】Redo Log 就是 WAL
- 什么是 WAL:
- WAL 的全称是 Write-Ahead Logging,中文称为预写式日志,是一种数据安全写入机制。在 MySQL 中,redo log 就是采用了 WAL 机制。
- 为什么使用WAL?
- 磁盘的写操作是随机 IO,比较耗性能。通过将每一次的更新操作先写入日志中,然后再写入磁盘,就可以将随机写操作转变为顺序写操作,从而提高性能。WAL 的核心在于将随机写转变为了顺序写,降低了客户端的延迟,提升了系统的吞吐量。
二、基本概念
InnoDB 引擎对数据的更新,是先将更新记录写入 redo log 日志,然后在系统空闲的时候或者是按照设定的更新策略再将日志中的内容更新到磁盘之中。这种技术可以大大减少 IO 操作的频率,提升数据刷新的效率。
- redo log:被称作重做日志,包括两部分:
- 一个是内存中的日志缓冲:
redo log buffer
- 另一个是磁盘上的日志文件:
redo log file
。
- 一个是内存中的日志缓冲:
- 当故障发生致使内存数据丢失后,InnoDB会在重启时,经过重放 redo,将Page恢复到崩溃之前的状态 通过Redo log可以实现事务的持久性 。
三、核心流程
3.1 脏页落盘流程
- mysql 每执行一条 DML 语句,先将记录写入 redo log buffer ( redo日志记录的是事务对数据库做了哪些修改 ) 。后续某个时间点再一次性将多个操作记录写到 redo log file
当进行数据页的修改操作时:
- 首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上。
- 页从缓冲池刷新回磁盘的操作并不是在每次页发生更新时触发,而是通过一种称为
CheckPoint
的机制刷新回磁盘。
3.2 CheckPoint
如果重做日志可以无限地增大,同时缓冲池也足够大,那么是不需要将缓冲池中页的新版本刷新回磁盘。因为当发生宕机时,完全可以通过重做日志来恢复整个数据库系统中的数据到宕机发生的时刻。
- 文件结构:
- 可以配置为一组文件,例如,4 个文件,每个文件大小为 1GB,总共可记录 4GB 的操作。
- 写入时从头开始写,写到末尾后又回到开头,形成循环写的机制。
- Write Position: 写入偏移量
- Checkpoint: 检查点
- 作用:
- 提速: 缩短数据库的恢复时间
- 刷脏: 缓冲池不够用时,将脏页刷新到磁盘
- 崩溃恢复: 重做日志不可用时,刷新脏页。
- 刷脏的时机:
- sharp checkpoint:强制落盘。把内存中所有的脏页都执行落盘操作。只有当关闭数据库之前才会执行