学习笔记之 MySQL redo log

164 阅读2分钟

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的磁盘文件体现