MySQL高级之属性的实现原理之日志

一、REDO日志(持久性)

1. 需求

  • InnoDB存储引擎是以页为单位来管理存储空间的。在真正访问页面之前,需要把在磁盘上的页缓存到内存中的Buffer Pool之后才可以访问。所有的变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页会以一定的频率(checkpoint机制)被刷入磁盘, 通过缓冲池来优化CPU和磁盘之间的鸿沟,这样就可以保证整体的性能不会下降太快。
  • 缓冲池可以帮助我们消除CPU和磁盘之间的鸿沟,checkpoint机制可以保证数据的最终落盘,然而由于checkpoint 并不是每次变更的时候就触发的,而是master线程隔一段时间去处理的。所以最坏的情况就是事务提交后,刚写完缓冲池,数据库宕机了,那么这段数据就是丢失的,无法恢复。这就破坏了数据库的持久性原则。
  • 因此我们引入了redo日志,将对数据进行的操作在刷盘到磁盘之前,都先记录在redo日志中,只有写入了redo日志中,才算真正进行了提交,随后再将数据刷盘到磁盘中(WAL技术,即Write-Ahead Logging),此时如果数据提交之后数据库宕机了也没有关系,当数据库重启之后,数据库会根据记录的redo日志,来对数据进行恢复。(默认是提交之后就会写入redo日志,但也可以进行更改)

2. 概述

  • REDO LOG称为重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。
  • REDO LOG是存储引擎层(innodb)生成的日志,记录的是"物理级别"上的页修改操作,比如页号xxx、 偏移量yy写入了’zz’数据。主要为了保证数据的可靠性。
  • 在事务中,将缓存区的数据更新之后,才会将“物理级别”的修改操作写入REDO LOG中。

3. 组成

  • 重做日志的缓冲 (redo log buffer) ,保存在内存中,是易失的。
  • 重做日志文件 (redo log file) ,保存在硬盘中,是持久的。

4. 流程

在这里插入图片描述

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

5. 刷盘策略

5.1 刷盘流程

  • redo log buffer刷盘到redo log file的过程并不是真正的刷到磁盘中去,只是刷入到文件系统缓存(page cache)中去(这是现代操作系统为了提高文件写入效率做的一个优化),真正的写入会交给系统自己来决定(比如page cache足够大了)。 那么对于InnoDB来说就存在一个问题, 如果交给系统来同步,同样如果系统宕机,那么数据也丢失了( 虽然整个系统宕机的概率还是比较小的)

5.2 参数设置

  • 针对上述情况,InnoDB给出innodb_flush_log_at_trx_commit参数,该参数控制commit提交事务时,如何将redo log buffer中的日志刷新到redo log file中。它支持三种策略
    1. 设置为0:表示每次事务提交时不进行任何操作。(系统默认master thread每隔1s进行一次重做日志的同步)。
      在这里插入图片描述

    2. 设置为1:表示每次事务提交时都将redo log buffer区内容写入page cache,并将page cache的内容写入redo.file中(默认值)。
      在这里插入图片描述

    3. 设置为2:表示每次事务提交时都只把redo log buffer内容写入page cache(同步),由os自己决定什么时候将page cache中的内容写入redo.file中(刷盘)。
      在这里插入图片描述

二、UNDO日志(原子性、一致性)

1. 基础概念

  • UNDO LOG称为回滚日志,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。
  • 是存储引擎层(innodb)生成的日志,记录的是逻辑操作日志,当我们对数据进行修改之后,undo日志中就会记录下来此次记录修改之前的版本,当需要回滚时,存储引擎(innodb)就会根据记录的信息进行原操作相反的操作,比如原操作是insert,就会进行delete。主要用于事务的回滚(undo log记录的是每个修改操作的逆操作)和一致非锁定读(undo log回滚行记录到某种特定的版本MVCC,即多版本并发控制)。
  • 在事务中,更新数据的前置操作其实是先把更新前的数据信息写入一个UNDO LOG。

2. 回滚细节

每当我们要对一条记录做改动时(这里的改动可以指INSERT、DELETE、 UPDATE),都需要"留一手"- - -把回滚时所需的东西记下来。比如:

  • 插入一条记录时,至少要把这条记录的主键值记下来,之后回滚的时候只需要把这个主键值对应的记录删掉就好了(对于每个INSERT,InnoDB存储引擎会完成一个DELETE)。
  • 删除了一条记录,至少要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中就好了。(对于每 个DELETE,InnoDB存储引擎会执行一个INSERT)
  • 修改了一条记录,至少要把修改这条记录前的旧值都记录下来,这样之后回滚时再把这条记录更新为旧值就好了。(对于每个UPDATE,InnoDB存储引擎会执行一个相反的UPDATE,将修改前的行放回去)。

MySQL把这些为了回滚而记录的这些内容称之为撤销日志或者回滚日志(即undo log)。注意,由于查询操作(SELECT)并不会修改任何用户录,所以在查询操作执行时,并不需要记录相应的undo日志。

3. UNDO LOG类型

3.1 insert undo log

  • insert undo log是指在insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(这是事务隔离性的要求), 故该undo log可以在事务提交后直接删除,不需要进行purge操作。

3.2 update undo log

  • update undo log记录的是对delete和update操作产生的undo log。该undo log可能需要提供给MVCC机制使用,因此不能在事务提交时就进行删除,提交时放入undo log链表,等待purge线程进行最后的删除。

4. UNDO LOG的存储

4.1 基本结构

  • InnoDB对undo log的管理采用段的方式,也就是回滚段(rollback segment)。每个回滚段记录了1024个undo log segment,而在每个undo log segment段中进行undo页的申请,undo页中记录的就是undo log。

4.2 页的重用

  • undo log在提交后,会被放到一个链表中,然后判断undo页的使用空间是否小于3/4,如果小于3/4的话,则表示当前的undo页可以被重用,那么它就不会被回收,其他事务的undo log可以记录在当前undo页的后面。

4.3 UNDO LOG和页的删除

  • 事务提交之后,对于UNDO LOG而言,如果是insert undo log可以直接删除;如果是update undo log则不可以,需要后续提供给MVCC使用。
  • 事务提交之后,对于UNDO LOG所在页而言,也不能删除。首先,要判断页是否可以重用;其次,如果该页是重用页,可能还包含了其他事务的数据;再者,页中的undo log可能要提供给MVCC使用。

4.4 回滚段与事务

  • 每个事务只会使用一个回滚段,一个回滚段在同一时刻可能会服务于多个事务。
  • 当一个事务开始的时候,会制定一个回滚段,在事务进行的过程中,当数据被修改时,原始的数据会被复制到回滚段。
  • 在回滚段中,事务会不断填充盘区,直到事务结束或所有的空间被用完。如果当前的盘区不够用,事务会在段中请求扩展下一个盘区,如果所有已分配的盘区都被用完,事务会覆盖最初的盘区或者在回滚段允许的情况下扩展新的盘区来使用。
  • 回滚段存在于undo表空间中,在数据库中可以存在多个undo表空间,但同一时刻只能使用一个undo表空间。
  • 当事务提交时,InnoDB存储引擎会做以下两件事情
    1. 将undo log放入链表中,以供之后的purge。
    2. 操作判断undo log所在的页是否可以重用,若可以分配给下个事务使用。

4.5 回滚段的数据类型

  • 未提交的回滚数据(uncommitted undo information) :该数据所关联的事务并未提交,,用于实现读一致性,所以该数据不能被其他事务的数据覆盖。
  • 已经提交但未过期的回滚数据( committed undo information):该数据关联的事务已经提交,但是仍受到undo retention参数的保持时间的影响。
  • 事务已经提交并过期的数据(expired undoinformation):事务已经提交,而且数据保存时间已经超过undo retention参数指定的时间,属于已经过期的数据。当回滚段满了之后,会优先覆盖"事务已经提交并过期的数据"。

注意:事务提交后并不能马上删除undo log及undo log所在的页。是否可以最终删除undo log及undo log所在页由purge线程来判断。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值