redolog有什么用,是怎么工作的

redolog其实就是想干一件事:当一个事务commit了,那肯定是在内存中改了,但是在磁盘里未必。可能刚提交事务就宕机了,还没来得及写磁盘(并且也不会立刻写的,会隔一段时间才刷)。redolog就是要保证这个一致性。
那乍一想我每次内存更新磁盘就更新不就解决了,但这么粗暴的解决方式肯定有问题的:

  • 有时候你只修改了一个页的一个字节,但我却要刷写一个页,因为innoDB以页为单位读写
  • 一个事务有很多语句,一个语句有很有可能修改很多页。随机io开销太大了。

Q:那咋整?
A:用redo日志,你提交事务,可以先不随机io修改数据而是先写到磁盘中的一个位置上,这个位置叫redo日志。redolog降低了刷盘频率并且占用的空间非常小。同时它记录了页表空间的id等,刷盘很快。这个就叫WAL(Write-Ahead Logging,日志先行)。并且redolog只记载记录下对磁盘中某某页某某位置数据的修改结果,比如对 XXX 表空间中的 YYY 数据页 ZZZ 偏移量的地方做了AAA 更新,这样会节省很多磁盘空间。与数据库层的binlog完成一个事务写一次不同,redolog是存储引擎层的,他会在事务执行过程中不断记录。并且尽管redolog是磁盘的一块空间,但写入的过程是顺序的,因为它是一个循环的逻辑空间,如下图所示。需要注意实际上redo日志文件是若干文件组串起来的,这样就保证了redolog写满了咋办的问题。innoDB有个重做日志组,在重做日志组中,每个 redo log File 的大小是固定且一致的,假设每个 redo log File 设置的上限是 1 GB,那么总共就可以记录 2GB 的操作。这个写满了写那个,那个再写下一个都写满了再绕回一开始的写。脏页被刷写道磁盘后一开始的旧记录就没用了,所以这样是可行的。

所以redolog的优点就对应上面两个问题所在了:

  • 能够实现事务的持久性,让MySQL有crash-safe能力,保证事务只要提交就永久了
  • 将写操作变成了顺序写,提高磁盘io性能

redolog有什么用,是怎么工作的_第1张图片
lsn(有的好像也叫write pos)追上了checkpoint就代表redolog file满了,MySQL 不能再执行新的更新操作,也就是说 MySQL 会被阻塞,要停下来将 Buffer Pool 中的脏页刷新到磁盘中,然后标记 redo log 哪些记录可以被擦除,接着对旧的 redo log 记录进行擦除,等擦除完旧记录腾出了空间,checkpoint 就会往后移动(图中顺时针),然后 MySQL 恢复正常运行,继续执行新的更新操作。

具体工作如下:
redolog有什么用,是怎么工作的_第2张图片
其中最重要的是3!,其实这步保证了,其他的都好说了。那redolog的刷盘策略到底是啥呢?其实redolog buffer和redolog file之间还有一层缓冲,叫做文件系统缓存(page cache),这是操作系统为了提升写入效率的一个优化,专门用来缓存文件数据的。正常MySQL关闭、系统后台每隔1s、redolog buffer记录的写入量大于其空间一半都会触发写入redolog file。但除此之外还有一个参数可以控制事务写入的时机——innodb_flush_log_at_trx_commit
那这里有三种选择:

  • 设置为0 :表示每次事务提交时不进行刷盘操作。(由系统默认master thread每隔1s进行一次重做日志的同步) 第1步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝 第2步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值 第3步:当事务commit时,将redo log buffer中的内容刷新到 redo log file,对 redo log file采用追加 写的方式 第4步:定期将内存中修改的数据刷新到磁盘中
  • 设置为1 :表示每次事务提交时都将进行同步,刷盘操作( 默认值,安全性最好效率差些 )
  • 设置为2 :表示每次事务提交时都只把 redo log buffer 内容写入 page cache,不进行同步。由os自 己决定什么时候同步到磁盘文件。实际上这个比设置为0要安全一点,因为这个已经写进到操作系统的范畴里了,只要操作系统不崩就肯定可以写进磁盘的

这三个参数的数据安全性和写入性能的比较如下:
数据安全性:参数 1 > 参数 2 > 参数 0
写入性能:参数 0 > 参数 2> 参数 1
所以绝对要保证数据的持久性就选择1,如果可以容忍丢1s的数据那选0来提高效率,二者折中选2
redolog有什么用,是怎么工作的_第3张图片

那是如何写入redolog file的呢?也就是说过程是怎样的呢?
首先我们得先知道什么是mtr,也就是Mini-Transaction,即MySQL底层页面中的一次原子访问过程。比如,向某个索引对应的B+树中插入一条记录的过程就是一个Mini-Transaction。一个所谓的mtr可以包含一组redo日志,在进行崩溃恢复时这一组redo日志可以作为一个不可分割的整体。
redolog有什么用,是怎么工作的_第4张图片

一个mtr执行过程中可能产生若干条redo日志,这些redo日志是一个不可分割的组,所以其实并不是每生成一条redo日志,就将其插入到log buffer中,而是每个mtr运行过程中产生的日志先暂时存到一个地方,当该mtr结束的时候,将过程中产生的一组redo日志再全部复制到log buffer中。

你可能感兴趣的:(mysql,数据库,mysql)