1、前言
MySQL 有一个write ahead logging 即 WAL 机制,中文意思:提前写日志。顾名思义,就是在事务提交前先写日志,然后在写 sql 到 buffer pool,redo log 刷盘与 buffer pool 刷盘看配置。
redo log 即所谓的 mysql 恢复神器,mysql 在事务中执行 sql 的时候,会根据 sql 生成相应的 redo log 日志先写入到 redo log buffer 中,然后再进行相应的数据修改,最后提交事务响应客户端。
前面我们提到,mysql 修改数据页的时候,只是先修改 buffer pool 中的数据页。同理,写入 redo log buffer 也不是直接写磁盘,而是先写 redo log buffer。
redo log buffer
针对 log buffer 的写入是全局的,即有一个全部变量 buf_free,指明应该写入哪个位置。
buf_free 位置
如果有两个事务并行执行,那么针对两个事务会产生相应的 redo log,那么写入 log buffer 的时候,可能会交替写入。
交替写入
2、redo log 刷盘时机
redo log 就是为了保证 mysql 事务的持久性的,所以在事务提交之前需要先刷盘,刷盘时机是什么呢?
- log buffer 空间不足时,即 redo log 的日志已经占满了 log buffer 一半的空间,就算事务还在进行中,也得先刷盘。
- 事务提交的时候,需要刷盘
- 后台有线程不断刷
- 其他等等情况。
3、redo log 日志文件
默认情况下,redo log 在磁盘上会以 ib_logfile0、ib_logfile1 出现,redo log 就是写在这两个文件中(文件的个数可以调整到任意个,比如 ib_logfileN)。
日志文件
redo log 日志是循环写入到这两个文件的(默认情况下)。
redo日志只是为了系统奔溃后恢复脏页用的,如果对应的脏页已经刷新到了磁盘,也就是说即使现在系统奔溃,那么在重启后也用不着使用redo日志恢复该页面了,所以该redo日志也就没有存在的必要了,那么它占用的磁盘空间就可以被后续的redo日志所重用。也就是说:判断某些redo日志占用的磁盘空间是否可以覆盖的依据就是它对应的脏页是否已经
刷新到磁盘里。所以 redo log 有 一个 checkpoint 的概念。
checkpoint 点之前代表当前 redo log 文件中对应的哪些 buffer pool 中的脏页刷到磁盘上了,checkpoint 点之后代表已经写入的 redo log 文件(代表 buffer pool 没刷的脏页)和空闲空间(如果有空闲的话)。崩溃恢复时,只需要恢复 checkpoint 之后的为起点,然后再找到最后一块写入的问题(没有写入的空间不需要恢复)。
网友评论