这是我参与更文挑战的第4天,活动详情查看:更文挑战
一、前言
相关概念:
redo log
binlog
redo log
,是一种偏向物理性质的重要日志,记录着 “对哪个数据页中的什么记录,做了什么修改”。
redo log
本身是属于 InnoDB
存储引擎特有的一个东西。
binlog
叫做归档日志,里面记录的是偏向于逻辑性的日志,类似于 “对 user 表中 id=10的一行数据做了更新操作,更新以后的值是什么”
binlog
不是 InnoDB
存储引擎特有的日志文件,是属于 MySQL Server
的日志文件。
提交事务的时候,同时会写入 binlog
:
提交事务的时候,会把
redo log
日志写入磁盘文件中去,然后其实在提交事务的时候,还会把这次更新对应的binlog
日志写入到磁盘文件中去。
如图:
图中的 执行器,负责跟 InnoDB
进行交互,包括从磁盘里加载数据到 Buffer Pool
中进行缓存、写入 undo
日志、更新 Buffer Pool
里的数据,以及写入 redo log buffer
,redo log
刷入磁盘,写 binlog
等等。
步骤 5, 6 是提交事务开始的时候,属于提交事务的阶段。
二、binlog
日志的刷盘策略分析
binlog
日志,也有不同的刷盘策略,有一个 **sync_binlog
**参数可以控制 binlog
的刷盘策略,默认值 0。
sync_binlog
参数值:
- 0, 此时
binlog
写入磁盘的时候,不会直接进入磁盘文件,而是进入os cache
内存缓存。 - 1, 此时会强制在提交事务的时候,把
binlog
直接写入到磁盘文件里。
基于 binlog
和 redo log
完成事务的提交:
当把
binlog
写入磁盘文件之后,接着就会完成最终的事务提交,此时会把本次更新对应的binlog
文件名和这次更新的binlog
日志在文件里的位置,都写入到redo log
日志文件里去,同时在redo log
日志文件里写入一个commit
标记。
如图:
事务提交完成标准:5、6、7三个步骤都执行完毕。
此时,会有如下情况:
redo
写入磁盘文件之后,MySQL
宕机了
这个时候因为没有最终的事务
commit
标记在redo
日志里,所以此次事务可以判定为不成功。不会说
redo
日志文件里有这次更新的日志,但是binlog
日志文件里没有这次更新的日志,不会出现数据不一致的问题。
redo
写入磁盘文件之后,binlog
日志写入磁盘,MySQL
宕机了
因为
redo log
中的没有最终commit
标记,因此此时事务提交也是失败的。
三、更新数据
后台
IO
线程随机将内存更新后的脏数据刷回磁盘
MySQL
有一个后台的 IO
线程,会在之后某个时间里,随机的把内存 buffer pool
中的修改后的脏数据给刷回到磁盘上的数据文件里。
如图:
此时,崩溃会怎样?
在
IO
线程把脏数据刷回磁盘之前,哪怕MySQL
宕机崩溃也没关系,因为重启之后,会根据redo
日志恢复之前提交的事务更新到内存里去。
问题:为什么修改磁盘里的数据,要通过 IO
线程不定时的去执行?
异步操作,加快操作执行。