Loading... ## redo log `InnoDB` 存储引擎是**以页为单位**来管理存储空间的, 我们的增删改查操作本质上都是在访问**页面**, 如读取一条数据, 会把这个数据**所在的页**加载到内存中, 而不仅仅是这条数据本身, 这个页的默认大小是 `16KB`. 在事务中, 我们有一个特性: **持久性**, 指对于一个已提交的事务, 在事务提交后, 即使系统崩溃, 也要保证这个事务对数据库做的更改不会丢失, 那么我们如何保证这一点呢, 有一个简单粗暴的做法就是: **在事务提交之前, 将事务所修改的所有页面都刷新到磁盘**, 但这种做法有几个问题: * 刷新一个数据页太浪费了, 可能我们只修改了这个数据页中的一个字节, 但 `InnoDB` 所有操作都是基于页面的, 我们只修改一个字节就要刷新一个 16KB 的页到磁盘上台浪费了. * 随机 IO 刷起来比较慢, 一个事务可能包含了很多语句, 即使一条语句, 也可能修改了许多页面, 有可能修改的这些页面并不相邻, 那么这就需要进行很多次随机 IO, 这相对顺序 IO 来说很慢, 尤其对机械硬盘来说. 那么如何解决这个问题呢, `InnoDB` 采用了 **redo log** 机制来解决: <!-- more --> `redo log` 是 `Innodb` 存储引擎的特性, 即在更新数据时, 先将更新操作的结果放到 `redo log` 中, 他存储的是**物理日志**, 如 `将第 0 号表空间的 100 号页面的偏移量为 1000 处的值更新为 2。`, 然后过一段时间或待系统空闲时, 一起将多个更新操作在硬盘的数据文件上执行. 不过这个文件是有大小限制的, 当这个文件满的时候, 会删除最先写入的数据. > 你可能会问, 写到 `redo log` 不也是写入到磁盘吗, 这效率会更好吗, 是不是多此一举啊. 其实不是的, 首先每次写入 `redo log` 的数据是非常小的, 他只记录了这次修改的物理操作. 相较于之前要刷新 1 个或多个 16KB 的页面来说操作的数据量小多了, 而且写 `redo log` 是顺序 IO, 这整体会快很多. ## binlog `binlog` 是 `MySQL` 的功能, 所有存储引擎都可以使用. 记录的是**逻辑日志**, 如 `给 ID = 2 的数据行的 C 字段加 1`. 他是追加写入的, 当写到一定大小后, 会切换到写一个文件继续写, 不会覆盖原来的文件. 一般用来做数据库的备份和恢复使用. ## 两阶段提交 不过既然有两个日志, 那么如何保证不会出现写完 `read log`, 但还没写 `binlog` 的时候就宕机了呢, 为了解决这个问题, `MySQL` 采用了两阶段提交的方式: 1. 先写入 `redo log` 状态为 `prepare` 阶段. (存储引擎层 InnoDB) 2. 写 `binlog` (MySQL 服务层) 3. 提交事务, `redo log` 状态改为 `commit` 状态. (存储引擎层 InnoDB) 当系统出现异常宕机时: * binlog 有记录,redo log 状态 commit: 正常完成的事务,不需要恢复 * binlog 有记录,redo log 状态 prepare: 在 binlog 写完提交事务之前的 crash, 恢复操作:提交事务 * binlog 无记录,redo log 状态 prepare: 在 binlog写完之前的 crash, 恢复操作:回滚事务 * binlog 无记录,redo log 无记录: 在 redo log 写之前 crash, 恢复操作:回滚事务 ## 相关配置 `innodb_flush_log_at_trx_commit` 参数设置为 1, 表示每次事务的 `redo log` 都直接持久化到磁盘, 推荐设置为 1, 这样可以保证 MySQL 异常重启后**数据不会丢失**. `sync_binlog` 参数设置为 1, 表示每次事务的 `binlog` 都持久化到磁盘, 推荐设置为 1, 这样可以保证 `MySQL` 异常重启后 **binlog 不会丢失**. ## 总结 `redo log` 是 `InnoDB` 引擎的特性, 只对使用 `InnoDB` 引擎的表生效, 记录的是 **物理日志**, **有大小限制**, 他的主要目的**是为了保证事务的一致性和提升更新操作的效率**. `binlog` 是 MySQL 的功能, 所有存储引擎都可以使用, 记录的是 **逻辑日志**, **没有大小限制**, 他的主要目的是**用于备份和恢复数据使用**. 最后修改:2022 年 05 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果觉得我的文章对你有用,请我喝杯咖啡吧。