MySQL-06-RedoLog

本文详细介绍了InnoDB存储引擎的架构,包括内存池中的BufferPool、RedoLogBuffer和DoubleWrite机制。BufferPool用于缓存数据和索引,包含数据页、索引页、插入缓冲、自适应哈希索引、锁信息和数据字典。RedoLogBuffer确保数据可靠性,通过重做日志保证事务持久性。DoubleWrite机制则增强数据页的可靠性,防止操作系统缓冲写带来的问题。此外,文章还讨论了checkpoint机制和不同的日志刷新策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

InnoDB架构

架构图

在这里插入图片描述
上图详细显示了InnoDB存储引擎的体系架构,从图可见,InnoDB存储引擎由内存池,后台线程和磁盘文件三大部分组成。

InnoDB内存结构

  • BufferPool(缓冲池)
    InnoDB采用缓存机制来实现提升处理数据的效率,Buffer Pool就是执行缓存区域;
    Buffer Pool中包含data page数据页、index page索引页、insert buffer page插入缓冲页、adaptive hash index自适应哈希(热点哈希)、lock info锁信息、data dictionary数据字典; ​ Page(页)是Innodb存储的最基本结构,也是Innodb磁盘管理的最小单位;执行增删改时,缓存里的数据页和磁盘里的数据页不一致,该数据页为脏页; ​ 插入缓冲(Insert Buffer)是单独对于插入操作的执行缓存区,其原因在于执行插入操作相对复杂度高,要进行主键排序、索引树、插入算法等等,需要单独缓冲区; ​ 自适应哈希索引(Adaptive Hash Index)的结构是hash结构,即key-value,InnoDB会根据访问频率,来为热点页建立哈希索引,来提升查询的效率(将访问频率高的从B+TREE上取出再建立一个k-v结构的哈希索引); ​ 锁信息(lock info),存放行锁、 表锁等锁的信息; ​ 数据字典信息(Data Dictionary)中存放元数据信息,包括表结构、数据库名、表名、字段的数据类型、视图、索引、表字段信息、存储过程、触发器等内容;

  • RedoLogBuffer(重做日志缓冲)
    在这里插入图片描述
    Redo Log 机制,如果要存储数据则先存储数据的日志 ,目的是为保障一旦内存崩溃则可以从日志找修改的记录;重做日志保证了数据的可靠性,InnoDB采用了Write Ahead Log(预写日志)策略,即当事务提交时,先写重做日志,然后再择时将脏页写入磁盘,如果发生宕机导致数据丢失,就通过重做日志进行数据恢复;落盘成功后清除Redo Log File内容。
    Redo Log File是mysql默认创建的文件,在mysql目录中有两个文件即ib_logfile0、 ib_logfile1,Redo Log File默认为8MB可通过配置参数innodb_log_buffer_size来调整文件大小;ib_logfile0 和 id_logfile1在日志组中每个重做日志文件的大小都是一致的,并以【循环写入】的方式运行;InnoDB存储引擎先写入重做日志文件ib_logfile0,当文件被写满时会切换,写入 id_logfile1,切换后ib_logfile0会被清空(落盘),当id_logfile1文件被写满时再切换,写入 id_logfile0。

  • 重做日志的落盘机制
    Force Log at Commit机制实现事务的持久性,即当事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,然后事务的提交操作完成才算完成;为了确保每次日志都写入到重做日志文件,在将重做日志缓冲写入重做日志文件过程中,必须调用一次fsync操作(操作系统,最终实现持久化一定是有操作系统完成),将缓冲文件从文件系统缓存(OS Buffer)中真正写入磁盘。
    可以通过innodb_flush_log_at_trx_commit 来控制重做日志刷新到磁盘的策略,共有0、1、2三个参数值;参数默认值为1,表示事务提交必须进行一次fsync操作;0表示事务提交时不进行写入重做日志操作,该操作只在主线程中完成;2表示提交时写入重做日志,但是只写入文件系统缓存,不进行fsync操作;由此可见,设置为0时,性能最高,但是可能造成数据丢失,无法保障事务的一致性。
    在这里插入图片描述
    在这里插入图片描述

  • Double Write双写机制
    Double Write带给InnoDB存储引擎的是数据页的可靠性;
    在这里插入图片描述
    如上图所示,Double Write由两部分组成,一部分是内存中的double writebuffer,大小为2MB,另一部分是物理磁盘上共享表空间连续的128个页,大小也为2MB;在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是通过memcpy函数将脏页先复制到内存中的double write buffer区域,之后通过double write buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免操作系统缓冲写带来的问题;完成double write页的写入后,再将double wirite buffer中的页写入各个表空间文件中,如果操作系统在将页写入磁盘的过程中发生了崩溃,恢复过程时,InnoDB存储引擎可以从共享表空间中的double write中找到该页的一个副本,将其复制到表空间文件中,再应用RedoLog重做日志。
    在这里插入图片描述

  • CheckPoint检查点(择时) ,表示脏页写入到磁盘的时机,所以检查点也就意味着脏数据的写入。
    checkpoint作用

     - 缩短数据库的恢复时间
     - buffer pool空间不够用时,将脏页刷新到磁盘
     - redolog不可用时,刷新脏页
    

    checkpoint分类

     - sharp checkpoint完全检查点
     	数据库正常关闭时,会触发把所有的脏页都写入到磁盘上
     - fuzzy checkpoint模糊检查点(正常使用时)
        部分页写入磁盘,分为以下四种;
         -1- master thread checkpoint(定时) :以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘,这个过程是异步操作;
         -2- flush_lru_list checkpoint : 读取lru (Least Recently Used-最近最少使用) list列表,找到脏页,写入磁盘;
         -3- async/sync flush checkpoint :log file快满了,会批量的触发数据页回写,这个事件触发的时候又分为异步和同步,不可被覆盖的redolog占log file的比值:75%异步写、90%同步写。
         -4- dirty page too much checkpoint :默认是脏页占比75%的时候,就会触发落盘,将脏页写入磁盘;
    

redoLog剖析

  • Redo log是什么?
    首先我们先明确一下InnoDB的修改数据的基本流程,当我们想要修改DB上某一行数据的时候,InnoDB是把数据从磁盘读取到内存的缓冲池上进行修改。这个时候数据在内存中被修改,与磁盘中相比就存在了差异,我们称这种有差异的数据为脏页。InnoDB对脏页的处理不是每次生成脏页就将脏页刷新回磁盘,这样会产生海量的IO操作,严重影响InnoDB的处理性能。既然脏页与磁盘中的数据存在差异,那么如果在这期间DB出现故障就会造成数据的丢失。为了解决这个问题,redo log就应运而生了。

  • Redo log工作原理
    在讲Redo log工作原理之前,先来学习一下MySQL的一些基础:
    一、日志类型
    在这里插入图片描述
    redo log在数据库重启恢复的时候被使用,因为其属于物理日志的特性,恢复速度远快于逻辑日志。而我们经常使用的binlog就属于典型的逻辑日志。

    二、 checkpoint
    checkpoint本身是比较复杂的,checkpoint所做的事就是把脏页给刷新回磁盘。所以,当DB重启恢复时,只需要恢复checkpoint之后的数据。这样就能大大缩短恢复时间。当然checkpoint还有其他的作用。

    三、 LSN(Log Sequence Number)
    LSN实际上就是InnoDB使用的一个版本标记的计数,它是一个单调递增的值。数据页和redo log都有各自的LSN。我们可以根据数据页中的LSN值和redo log中LSN的值判断需要恢复的redo log的位置和大小。

    四、 工作原理
    说白了,redo log就是存储了数据被修改后的值。当我们提交一个事务时,InnoDB会先去把要修改的数据写入日志,然后再去修改缓冲池里面的真正数据页。redo log本身也由两部分所构成即重做日志缓冲(redo log buffer)和重做日志文件(redo log file)。这样的设计同样也是为了调和内存与磁盘的速度差异。InnoDB写入磁盘的策略可以通过innodb_flush_log_at_trx_commit这个参数来控制。
    在这里插入图片描述

    当该值为1时,当然是最安全的,但是数据库性能会受一定影响。
    为0时性能较好,但是会丢失掉master thread还没刷新进磁盘部分的数据。

    这里简单介绍一下master thread,这是InnoDB一个在后台运行的主线程,从名字就能看出这个线程相当的重要。它做的主要工作包括但不限于:刷新日志缓冲,合并插入缓冲,刷新脏页等。master thread大致分为每秒运行一次的操作和每10秒运行一次的操作。master thread中刷新数据,属于checkpoint的一种。所以如果在master thread在刷新日志的间隙,DB出现故障那么将丢失掉这部分数据。
    当该值为2时,当DB发生故障能恢复数据。但如果操作系统也出现宕机,那么就会丢失掉,文件系统没有及时写入磁盘的数据。
    这里说明一下,innodb_flush_log_at_trx_commit设为非0的值,并不是说不会在master thread中刷新日志了。master thread刷新日志是在不断进行的,所以redo log写入磁盘是在持续的写入。

    五、 宕机恢复
    DB宕机后重启,InnoDB会首先去查看数据页中的LSN的数值。这个值代表数据页被刷新回磁盘的LSN的大小。然后再去查看redo log的LSN的大小。如果数据页中的LSN值大说明数据页领先于redo log刷新回磁盘,不需要进行恢复。反之需要从redo log中恢复数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值