redo log
为什么需要redo log?
- 大部分修改数据都在内存中,只有满足一定条件才会将内存中的脏页刷到磁盘中。
- 内存数据会因为系统或者其他意外因素丢失,不满足持久性
- 刷新一个完成页的成本太大了,有时候我们只是修改了某个页中的一条信息,但是我们去刷新整页信息则显得代价太大
- 我们的某次更改,可能会涉及很多页,那么针对这么多页的IO就是随机IO,性能很低
解决方案 redo log
- 针对上面的情况,我们可以设计一个重做日志,重做日志中我们只记录数据的变化
# 比如我们记录了某次更新
# 将A表中的某条数据从1000变成了1001
-
redo 日志的好处
- redo 日志的大小非常小,只记录一些变更的关键信息
- redo 日志是顺序IO而不是随机IO
1. redo log 的格式
redo 日志的通用结构
- type: 该条日志的类型
- space ID: 表空间ID
- page number: 页号
- data: 日志的具体内容
- 实际上,一条插入信息可能涉及很多变化,聚簇索引中叶子节点的数据页发生变化之外,页中的数据,诸如页头页尾的部分信息,还有很多统计信息都会发生变化。 redo log 在记录这种信息的时候可能产生很多条Log 为了解决这个问题, redo log在设计的时候也采用了很多方案,诸如根据插入的类型涉及的改动来分类等等。
2. redo log 缓冲区
虽然redo log将随机IO变成了顺序IO, 但是机械硬盘的读写速度过慢还是硬伤,所以不能有一条就刷新一条到磁盘
MySQL 使用 一段内存空间 名为 log buffer 来存放redo log
innodb_log_buffer_size = 16MB
我们可以通过上述参数来调整这个buffer的大小,默认值为16MB
什么时候会将redo刷新到磁盘?
- 当 log buffer的空间被使用了一半时, innodb会把这部分redo log刷新到磁盘
- 事务提交时
- 将某个脏页刷新到磁盘前 会将涉及这个脏页的redo log以及之前的redo log也刷新到磁盘
- 后台线程自动刷新
- 停止服务时
- checkpoint时
磁盘中的redo 长啥样?
- 我们在数据目录下 发现的 ib_logfile[n] 其实就是redo log的磁盘文件体现