一、Undo Log
1、作用
- 用于事务回滚,保证事务的原子性
- 与 Read View 共同实现 MVCC
2、日志内容
对于 INSERT 操作,Undo Log 会记录新插入行的主键值;
对于 DELETE 操作,Undo Log 会记录被删除行的所有数据;
对于 UPDATE 操作,Undo Log 会记录被更新行的所有旧值。
除此之外还有事务 id、旧版本指针、日志编号、对应记录所在表的 id 等等。
3、什么时候会生成
当事务进行 INSERT、DELETE 或 UPDATE 操作时,InnoDB 会生成相应的 Undo Log 来记录数据的变更。
4、什么时候刷盘
生成的 Undo Log 会被写入到内存中的 Buffer Pool。
Buffer Pool 的刷盘时机:
- 后台线程定期刷盘;
- 手动刷新;
- Redo Log Buffer 满了;
- Buffer Pool 空间不足。
5、Buffer Pool 的作用
避免频繁的硬盘 IO,在内存中设置了缓冲池提高数据库的读写性能。
读数据时会将数据页从数据库读到缓冲池。
写数据时会将数据先写到缓冲池中,并将所在的页设为脏页,之后进行异步刷盘。
二、Redo Log
1、作用
- 用于持久化 Buffer Pool,防止断电导致内存中的脏页丢失。
- 将写操作从随机写变成了顺序写,提高了 MySQL 写入磁盘的性能。
2、日志内容
记录某个数据页做了什么修改,如对 XXX 表空间的 YYY 数据页 ZZZ 偏移量的地方做了 AAA 更新。
3、什么时候会生成
当记录修改后,InnoDB 会将本次的修改记录到 Redo Log 中。
4、数据页要刷盘,Redo Log 也要刷盘,为什么多此一举?
在事务提交时,只需将 Redo Log 持久化到磁盘就能保证发生断电的情况下能够将数据恢复到最新状态,不需要等 Buffer Pool 的脏页数据刷盘。
为什么不直接将脏页数据刷盘? 写入 Redo Log 是追加操作,磁盘顺序是顺序写。而写入数据需要先找到位置再写,是随机写。顺序写比随机写高效的多。
5、什么时候刷盘
执行一个事务的过程中,每产生一条 Redo Log,会先写到 Redo Log Buffer(存于用户空间的内存),之后在下面几个时机进行刷盘:
- MySQL 正常关闭情况下;
- Redo Log Buffer 记录的写入量大于一半时;
- InnoDB 后台线程每隔1秒;
- 事务提交时(由参数控制)
a. 参数为 0 ,不会主动刷盘;
b. 参数为 1 ,主动刷盘;
c. 参数为 2 ,写到 Redo Log 文件(在内核空间的内存)
6、Redo Log 文件满了会发生什么?
MySQL 不能再执行修改操作,会停下来先将 Buffer Pool 中的脏页刷盘,之后擦除掉 Redo Log 的旧记录。
三、Binlog
1、作用
- 用于主从复制
- 用于备份
2、日志内容
有 3 种格式,分别是 STATEMENT(记录每条修改数的 SQL 语句)、ROW(记录行数据执行完 SQL 的状态)、MIXED(根据情况自动使用前两种模式)。
3、如何实现主从复制
- 主库写入 binlog,提交事务,并更新本地数据。
- 将 binlog 复制到所有从库上。
- 从库回放 binlog。
4、什么时候刷盘
事务执行过程中,先把日志写到 binlog cache(在用户空间的内存),事务提交时会把 binlog cache 写入到 binlog 文件(在内核空间的内存)中,并清空 binlog cache。
通过 sync_binlog 参数控制 binlog 文件刷盘频率:
- 参数为 0 时,不主动刷盘;
- 参数为 1 时,每次提交事务主动刷盘;
- 参数为 N 时,积累 N 个事务再进行刷盘。