日志文件种类
•redo log 重做日志,是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢复
事务执行过程中,生成的 redolog 会在 redolog buffer 中,也就是在内存中,等事务提交的时候,会把 redolog 写入磁盘。
•undo log 回滚日志,是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC。
undo log保证了ACID特性中的原子性,事务没有提交前,修改前旧数据写入 Undo Log Buffer 内存,后台会刷入磁盘 undo 日志,事务回滚优先读取 Undo Log Buffer 内存中的旧数据,执行反向操作实现回滚;如果内存中不存在,则读取磁盘 undo log 文件.
具体操作:是回滚时读取undo log中数据,然后做原操作相反的操作,比如delete一条操作,就会把记录记到undo log中,执行回滚时,读取undo log数据,进行insert操作,相反插入回滚就会做删除操作,更新操作回滚就直接更新旧值。
• bin log 二进制日志,是 Server 层生成的日志,主要用于数据备份和主从复制;
- MySQL完成一条更新操作,Server层会生成一条binlog,等事务提交时,将事务执行中产生的所有binlog写入binlog文件。
- 是 Server 层生成的日志,所有引擎都可以使用。
- 是追加写,写满一个文件就继续写,不会覆盖之前的日志,保存全量日志,用于数据备份和主从复制。
- 记录了所有数据库表结构变更和表数据修改的日志,不会记录查询类的操作。
- 包含三种模式:statement,row,mixed
格式 记录内容 优点 缺点 STATEMENT 原始 SQL 语句 日志小 动态函数主从不一致 ROW 行变更前后数据 复制安全无歧义 大数据量 binlog 体积大 MIXED 自动切换二者 兼顾体积与安全 极少场景仍有隐患
- •relay log 中继日志,用于主从复制场景下,slave通过io线程拷贝master的bin log后本地生成的日志
- • 慢查询日志,用于记录执行时间过长的sql,需要设置阈值后手动开启
redo log、undo log、bin log详细区分
redo‑binlog 两阶段提交
两阶段提交的时序:
三者刷盘时机:
undo log :异步刷盘,事务提交不强制刷盘,定期刷盘+条件触发
redo log :prepare阶段就刷盘
bin log :事务commit之前刷盘
有了undolog为啥还需要redolog呢?
redo log 和 undo log 这两种日志是属于 InnoDB 存储引擎的日志,它们的区别在于:
undo log 保存修改前旧数据,用于事务失败回滚,保证原子性;记录了此次事务「开始前」的数据状态,记录的是更新之前的值;
redo log 记录修改之后的新变化,事务提交后机器崩溃,依靠 redo log 重做改动保证持久性。记录了此次事务「完成后」的数据状态,记录的是更新之后的值;
undo 只有旧版本,不能恢复已经提交成功的新数据,所以必须要有 redo log。
为什么用binlog还要redolog
1.binlog是服务层逻辑日志,服务于备份与主从复制,不能用于 InnoDB 崩溃恢复。
2.redo log 是InnoDB 存储引擎日志,用于崩溃恢复,宕机后恢复内存中尚未刷入 ibd 文件的数据页。
3.两阶段提交机制下:
先将 redo log 刷盘打上 prepare 标记,之后才写入 binlog 磁盘文件。如果故障发生在 redo prepare 完成、binlog 尚未写完,此时只有 prepare 状态的 redo,没有 binlog,重启后事务回 滚。依靠 redo 与 binlog 两份日志互相校验,保证数据一致性。
为什么要写RedoLog,而不是直接写到B+树里面?
性能提升:把大量随机磁盘 IO,转变成顺序 IO事务提交只需要写 redo log(顺序写),不需要立刻改动 B + 树磁盘。脏页交给后台线程慢慢刷盘。
崩溃恢复能力机器宕机,内存 Buffer Pool 全部丢失,内存脏页还没刷到 B + 树磁盘。 重启 MySQL,读取磁盘上的 redo log,把还没刷盘的数据页变更重新恢复到内存,保证数据不丢失。
Mysql的两次写
保障后台异步刷盘数据页到idb文件不会因为页断裂故障
我们常见的服务器一般都是Linux操作系统,Linux文件系统页(OS Page)的大小默认是4KB。而MySQL的页(Page)大小默认是16KB。MySQL程序是跑在Linux操作系统上的,需要跟操作系统交互,所以MySQL中一页数据刷到磁盘,要写4个文件系统里的页。
刷脏页断电时,有可能只写入部分数据,造成磁盘上数据页半损坏。redo log 记录的是页的变更操作,无法修复本身已经物理损坏的页。
doublewrite buffer 既有内存部分,也有磁盘备份区域。刷脏页先拷贝到内存 DWB,再持久化到磁盘 DWB;磁盘备份成功后,才写入真实 ibd 文件。机器崩溃后内存数据全部丢失,恢复依靠磁盘上 doublewrite 保存的完整页副本修复破碎的数据页,修复完成再执行 redo log。
不同崩溃阶段处理方式
| 崩溃发生阶段 | 磁盘 DWB 备份状态 | ibd 数据页状态 | 恢复行为 |
|---|---|---|---|
| ②拷贝内存 DWB 阶段 | 无备份 | ibd 页完好(旧版本) | 丢弃内存数据,直接 redo log 重放 |
| ③写磁盘 DWB 中途 | 备份页本身损坏无效 | ibd 页完好(旧版本) | 丢弃损坏 DWB 备份,走 redo log 重放 |
| ③成功,④写 ibd 中途 | DWB 备份完整有效 | ibd 页断裂损坏 | 先用 DWB 磁盘副本修复破碎页,再执行 redo log 重放 |
| ④ibd 全部写完之后 | 备份过期可被覆盖 | ibd 页完整最新 | 不需要 DWB 修复,直接 redo log 恢复 |