天天看点

redo log、undo log

redo log(重做日志)

redo log是一种物理日志

redo log日志称为重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。只需要把修改了哪些东西记录一下就好.比如某个事务将系统表空间中第10号页面中偏移量为100处的那个字节的值1改成2.我们只需要记录一下:将第0号表空间的10号页面的偏移量为100处的值更新为2.lnnoDB引擎的事务采用了WAL技术(Write -Ahead Logging),这种技术的思想就是先写日志,再写磁盘,只有日志写入成功,才算事务提交成功,这里的日志就是redo log。当发生宕机且数据来刷到磁盘的时候,可从通过redo log来恢复,保证ACID中的D,这就是redo log的作用。

组成部分

重做日志缓存(redo log buff):

重做日志的缓冲(redo log buffer),保存在内存中,是易失的。在服务器启动时就向操作系统申请了一大片称之为redo log buffer的连续内存空间,翻译成中文就是redo日志缓冲区。这片内存空间被划分成若干个连续的redo log block。一个redo log block占用512字节大小。

重做日志文件(redo log):

重做日志文件(redologfile),保存在硬盘中,是持久的。

redo log 是物理日志,记载着每次在某个页上做了什么修改。写redo log也是需要写磁盘的,但它的好处就是顺序IO(我们都知道顺序IO比随机IO快非常多),写入的速度很快。

写入机制

  • 事务开始之后,就开始产生 redo log 日志了,在事务执行的过程中,redo log开始逐步落盘。
  • 当对应事务的脏页写入到磁盘之后,redo log 的使命就完成了,它所占用的空间也就可以被覆盖了。
  • InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB。从头开始写,写到末尾就又回到开头循环写
redo log、undo log
  • write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。
  • checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
  • write pos 和 checkpoint 之间的的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。

show variables like '%innodb_log%'每个InnoDB存储引擎至少有1个重做日志文件组(group),每个文件组至少有2个重做日志文 件,默认为ib_logfile0和ib_logfile1。

工作流程:

redo log、undo log
  • 第1步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝
  • 第⒉步:生成一条重做日志并写入redo log buffer ,记录的是数据被修改后的值
  • 第3步:当事务commit时,将redo log buffer中的内容刷新到redolog file ,对redo log file采用追加写的方式
  • 第4步:定期将内存中修改的数据刷新到磁盘中

刷盘策略

redo log、undo log

​ innodb_flush_log_at_trx_commit=1(默认)

  • 设置为0:表示每次事务提交时不进行刷盘操作。(系统黙认master thread每隔1s进行一次重做日志的同步)
  • 设置为1:表示每次事务提交时都将进行同步,刷盘操作
  • 设置为2:表示每次事务提交时都只把 redo log buffer内容写入page cache,不进行同步。由os自己决定什么时候同步到磁盘文件。

另外,​

​InnoDB​

​​ 存储引擎有一个后台线程,每隔1 秒,就会把 redo log buffer 中的内容写到文件系统缓存(​

​page cache​

​),然后调用 fsync刷盘。

也就是说,一个没有提交事务的 redo log 记录,也可能会刷盘。

undo log(回滚日志)

undo log是一种逻辑日志

undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。

作用

  • 提供事务回滚操作(undo log实现事务的原子性)
  • 提供多版本控制(MVCC)undo log实现多版本并发控制

存储机制

​ undo log的存储由InnoDB存储引擎实现,数据保存在InnoDB的数据文件中。在InnoDB存储引擎中,undo log是采用分段(segment)的方式进行存储的。rollback segment称为回滚段,每个回滚段中有1024个undo log segment。在MySQL5.5之前,只支持1个rollback segment,也就是只能记录1024个undo操作。在MySQL5.5之后,可以支持128个rollback segment,分别从resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成,即总共可以记录128 * 1024个undo操作。

redo log、undo log

如上图,可以看到,undo log日志里面不仅存放着数据更新前的记录,还记录着RowID、事务ID、回滚指针。其中事务ID每次递增,回滚指针第一次如果是insert语句的话,回滚指针为NULL,第二次update之后的undo log的回滚指针就会指向刚刚那一条undo log日志,依次类推,就会形成一条undo log的回滚链,方便找到该条记录的历史版本。

工作原理