目录
一、binlong
1、binlog介绍
作用
特点
2、日志格式
3、写入流程
二、redo log
1、redo log作用
2、redo log如何写入
3、怎么提交数据进行刷盘
4、奔溃恢复流程
三、undolog
一、binlong
1、binlog介绍
作用
binlog是 mysql server 层的一种二进制日志,用来记录数据库的写入操作,并以"事务"的形式保存在磁盘上,主要的使用场景有主从复制和数据恢复。
特点
- 记录了对 MySQL 数据库执行了更改的所有操作,包括表结构变更(CREATE、ALTER、DROP TABLE…)、表数据修改(INSERT、UPDATE、DELETE...),但不包括 SELECT 和 SHOW 这类操作,因为这类操作对数据本身并没有修改;若更改操作并未导致数据库变化,那么该操作也会写入 binlog
- binlog是追加写,写到一定大小会切换到下一个,并不会覆盖以前的日志。
2、日志格式
- statement:只记录执行的 SQL,不需要记录每一行数据的变化,因此极大的减少了 binlog 的日志量,但是类似 set update_time=now() 这种情况,可能会导致主从数据不一致。
- row:记录SQL涉及到的每行数据的修改,由于要记录每一行数据的变化,因此缺点是会产生大量的日志,mysql 5.7.7之后默认 row 模式
- mixed:两种方案折中,MySQL会判断这条SQL语句是否会引起数据不一致,如果是,就用row模式,否则就用statement模式
3、写入流程
先把日志写到binlog cache,事务提交的时候,再根据刷盘规则将binlog cache写入文件。
默认情况:每次提交事务都会执行 write + fsync
write:将 mysql 缓存写到文件系统的 page cache,并没有把数据持久化到磁盘,速度比较快
fsync:文件系统的 page cache 持久化到磁盘
二、redo log
1、redo log作用
- redo log (重做日志)是InnoDB存储引擎产生的,记录事务对数据页的修改。奔溃恢复时,重启后InnoDB会使用redo log恢复数据,保证了数据的持久性。
- 每一次更新都需要写到磁盘上。然后磁盘也要找到对应的记录,然后再更新,整个过程IO成本、查找成本太大,为了解决这个问题,MySQL的设计者采用了WAL技术来解决。WAL全称是Write Ahead Logging,意思就是先写日志,再写磁盘。
2、redo log如何写入
redo log是循环写的
- write pos:当前记录的位置,一边写一边后移
- checkpoint:当前要擦除的位置,也是往后推移并且循环的,脏页刷盘,checkponit往后移。擦除记录之前要把记录更新到数据文件中。
- 绿色的部分表示可以记录新的操作,是未刷入磁盘的日志。如果write pos追上了check point,表示redo log满了,这个时候就不能继续执行新的操作,需要停下擦除一些记录,并且把check point往后推进。
3、怎么提交数据进行刷盘
二阶段提交:通过二阶段提交保证奔溃恢复时不会有丢失事务数据或者主从不一致的问题
InnoDB事务提交之前并不是直接写redo log,而是使用了二阶段提交,将redo log的写出拆成了两个步骤:prepare 和 commit,这就是"两阶段提交"。
4、奔溃恢复流程
三、undolog
InnoDB事务修改数据之前会记录undo log并且持久化,undo log通过回滚事务指针形成了链表。
使用场景:
1、MVCC
2、通过rollback主动回滚事务
3、崩溃恢复未完成的事务通过undo log回滚
参考:
binlog、redolog、undolog - 知乎