美文网首页MySQL
MySQL innoDB——redo log/undo log

MySQL innoDB——redo log/undo log

作者: 茶树丶ccha | 来源:发表于2018-07-10 15:41 被阅读0次

    redo(记录了事务的行为,可以很好的通过其对页进行“重做”操作)

    • 包含易失的redo log buffer和持久的redo log file两部分
    • 存于redo log file(重做日志文件中)
    • 维护持久性
    • 页操作

    在一个事务中的每一次SQL操作之后都会写入一个redo log到buffer中,在最后COMMIT的时候,必须先将该事务的所有日志写入到redo log file进行持久化(这里的写入是顺序写的),待事务的COMMIT操作完成才算完成。

    redo
    参数 innodb_flush_log_at_trx_commit 用来控制重做日志刷新到磁盘的策略,该参数有3个值:0、1和2。
    0:表示事务提交时不进行写redo log file的操作,这个操作仅在master thread中完成(master thread每隔1秒进行一次fsync操作)。
    1:默认值,表示每次事务提交时进行写redo log file的操作。
    2:表示事务提交时将redo log写入文件,不过仅写入文件系统的缓存中,不进行fsync操作。

    对比binlog

    binlog为了解决Mysql主从备份而产生 
    * 内部XA:redo log和bin log的数据一直性和完整性的保证 
    * 外部XA:分布式事务
    
    内部XA(二段式提交),由于需要遵循WAL原则,binlog的过程需要嵌入到事务提交的流程中: 
    * prepare过程 
    * commit过程
    

    在MySQL数据库中还有一种二进制日志(binlog),从表面上来看它和redo log很相似,都是记录了对数据库操作的日志,但是,它们有着非常大的不同。

    • redo log是在MySQL的InnoDB引擎层产生,而binlog则是在MySQL的上层产生,它不仅针对InnoDB引擎,其他任何引擎对于数据库的更改都会产生binlog。
    • 两种日志记录的内容形式不同,binlog是一种逻辑日志,其记录的是对应的SQL语句。而redo log则是记录的物理格式日志,其记录的是对于每个页的修改。
    • 两种日志记录写入磁盘的时间点不同,binlog只在事务提交完成后一次性写入,而redo log在上面也说了是在事务进行中不断被写入,这表现为日志并不是随事务提交的顺序进行写入的。

    undo

    • 分为insert undo log(insert,insert只对本身事务可见,对其他事务无影响)和update undo log(update/delete)
    • 存于数据库中的undo segment(段)中
    • 用于回滚
    • 用于MVCC(实现非锁定读),读取一行记录时,若已被其他事务占据,则通过undo读取之前的版本
    • 维护原子性
    • 行操作(回滚行记录到某个版本)
      undo是逻辑日志,只是将数据库逻辑的恢复到执行语句或事务之前。

    InnoDB存储引擎的行结构

    InnoDB表数据的组织方式为主键聚簇索引,二级索引中采用的是(索引键值, 主键键值)的组合来唯一确定一条记录。
    InnoDB表数据为主键聚簇索引,mysql默认为每个索引行添加了4个隐藏的字段,分别是:

    • DB_ROW_ID:InnoDB引擎中一个表只能有一个主键,用于聚簇索引,如果表没有定义主键会选择第一个非Null的唯一索引作为主键,如果还没有,生成一个隐藏的DB_ROW_ID作为主键构造聚簇索引。
    • DB_TRX_ID:最近更改该行数据的事务ID。
    • DB_ROLL_PTR:undo log的指针,用于记录之前历史数据在undo log中的位置。
    • DELETE BIT:索引删除标志,如果DB删除了一条数据,是优先通知索引将该标志位设置为1,然后通过(purge)清除线程去异步删除真实的数据。


    简化过程

    不需要实时以同步的方式刷盘,数据可以后台异步写入磁盘(根据 innodb_flush_log_at_trx_commit参数值0,1,2来决定)
    redo log写入磁盘是顺序IO
    undo log也写入到redo log中

    redo 缓存刷盘规则:

    • 事务提交时
    • 当log buffer 中一半的内存空间已经被使用时
    • log checkpoint时

    check point
    check point机制是为了减少实例恢复的时间(如果在某个时间点,脏页的数据被刷新到了磁盘,系统就把这个刷新的时间点记录到redo log的结尾位置,在进行恢复数据的时候,checkpoint时间点之前的数据就不需要进行恢复了,可以缩短时间)

    • 缓冲池不够用时,触发checkpoint,将脏页刷盘
    • 重做日志不够用时,刷新磁盘

    脏页:一般业务运行过程中,当业务需要对某张的某行数据进行修改的时候,innodb会先将该数据从磁盘读取到缓存中去,然后在缓存中对这条数据进行修改,这样缓存中的数据就和磁盘的数据不一致了,这个时候缓存中的数据就称为dirty page,只有当脏页统一刷新到磁盘中才会是clean page

    在COMMIT的时候,InnoDB不会将dirty data page写盘。之所以强调这个是因为,很容易让人想到,提交改变就是将所有东西写到一个持久媒介上。
    其实,commit时只有log记录需要写。写dirty data page只可能发生在overflow或checkpoint时刻,因为它们的内容是多余的。
    

    参考内容

    相关文章

      网友评论

        本文标题:MySQL innoDB——redo log/undo log

        本文链接:https://www.haomeiwen.com/subject/gfmtpftx.html