• 14.Mysql之redo log -checkpoint浅谈01


    1.前景

      在Mysql中,就我自己的角度来看到所有的日志文件,那么我认为redo log 和undo log是Mysql日志中必不可少的一节。

    2. Redo Log 特点

      这里先要介绍一下WAL机制:当执行提交事务之后,并不是直接修改到数据文件中的,而是先要保证将相关的操作日志记录到Redo文件中,数据库后台会根据自身的机制(这里的内存中的数据页刷新到磁盘上的机制有再innodb存储引擎一章中进行详解)将内存中的脏数据刷新到磁盘中。之所以这么做主要有一下两点:

    • 写入数据文件时随机I/O比较慢,用户执行提交之后一定要等到数据文件同步写入完成后才返回成功(这里个人理解是如果没有redo log的话,当执行commit 后,会出现短暂性的阻塞),这样用户体验就会很差(这里说明内存中的脏页刷盘是随机写的)  
    • 如果提交一个很大的事务要就进行大量的随机I/O同步写入,那么数据库就会有抖动的,
    • 做自动故障恢复(前滚)

      综合以上三点考虑引入了Redo日志,每次事务提交之后,都先将相关的操作日志写入Redo日志文件中,并且都追加到文件末尾,这是一个顺序io,这样将每次同步的随机i/O转换为顺序i/O,对脏数据的刷新在后台可以进行阶段性操作,并且可以做相关的i/O合并,是整体性能得到提升。其中做自动故障恢复主要是通过redo log恢复数据库崩溃前时内存中的状态,保证数据库在崩溃时事务不会丢失。  

      通常,我们往往会在innodb存储引擎的数据目录下看到会有两个名为ib_logfile0和ib_logfile1的文件,这两个文件在Mysql官方文档上将其称为innodb存储引擎的日志文件。该日志主要是用来保证事务的原子性和持久性。

      其中,它保证事务的持久性主要是由两部分组成,一是内存中的重做日志缓冲(redo log buffer),该大小主要是由innodb_log_buffer_size参数控制,而是由重做日志文件(redo log file),主要是由参数innodb_log_file_size控制,

    3.Redo Log格式 

      Redo Log日志格式主要分为两种:物理日志和逻辑日志

      其中物理日志就是将变化对象的新旧状态都记录到日志中,而逻辑日志主要记录的就是逻辑语句,类似于Mysql中binlog,优势在于日志量非常少,

      思考:为什么Redo log要用物理日志和逻辑日志两种混合形态进行记录吗?

    4.checkpoint概念(略谈)

      众所周知,当数据库发生崩溃时,可以利用redo log的前滚机制进行数据实例的恢复,但是如果Redo文件足够大,那么这样的数据库在做实例恢复时所需要的时间就会变得足够长,显示这时不允许的,因此,在数据库引入了checkpoint(检查点)机制

      checkpoint作用

    • 缩短数据库的恢复时间
    • 缓冲池不够用时,将脏页刷新到磁盘
    • 重做日志不可用时,刷新脏页

      checkpoint刷新策略:

      因此,当数据库发生宕机时,数据库不需要重做所有的日志,因为checkpoint之前的数据都已经刷新到磁盘。故数据库只需要对checkpoint后的重做日志进行恢复,这样就大大地减少了恢复时间。  

      此外,当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若此页为脏页,那么需要强行执行checkpoint,将脏页也就是页的新版本刷回到磁盘。

      重做日志不可用的情况是,因为当前的重做日志是循环使用的,并不是让其无限增大,重做日志可以被重用的部分是指这些重做日志已经不再需要,即当数据库发生宕机时,数据库恢复操作不需要这部分的重做日志,因此这部分就可以被覆盖重用,若此时重做日志还需要使用,那么就必须强制产生Checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置(这时会就出现极客林晓斌所说数据库抖动的情况,其实这种情况的产生大部分是由于写入的长事务到数据库中)。

      那么checkpoint是如何具体判断刷新?

      对于innodb存储引擎而言,其主要是通过LSN(Log Sequence Number)来标记版本的,可以通过如下命令进行查看:  

    ---
    LOG
    ---
    Log sequence number 996682662      //Redo 日志缓冲区中的LSN
    Log flushed up to   996682662      //Redo 日志文件中的LSN
    Pages flushed up to 996682662      //写入磁盘中的数据页对应的LSN
    Last checkpoint at  996682653      //最后一个checkpoint对应的LSN

      在innodb存储引擎中,Checkpoint发生的时间、条件以及脏页的选择等都非常复杂。而Checkpoint所做的事情无非是将缓冲池中的脏页刷回到磁盘,不同在于每次刷新多少页到磁盘,每次从哪里取脏页。以及什么时间触发checkpoint。在innodb存储引擎中,主要有两种checkpoint:一种是Sharp checkpoint(全量检查点),另一种是Fuzzy checkpoint(模糊检查点).

      sharp checkpoint 发生在数据库关闭时将所有的脏页都刷回磁盘,这时默认的工作方式,由参数innodb_fast_shutdown=1控制

      如果在数据库运行的阶段也采用sharp checkpoint,那么数据库的可用性就会受到很大的影响,故在innodb存储引擎内部使用Fuzzy Checkpoint进行页的刷新,即只是刷新部分页,而不是刷新所有的脏页到磁盘。 

      在innodb存储引擎中可能发生如下几种情况的Fuzzy Checkpoint(这个应该会在innodb之存储引擎篇中详解): 

    • Master thread Checkpoint
    • Flush_LRU_LIST checkpoint
    • Async/sync Flush Checkpoint
    • Dirty page too much Checkpoint

    5.Redo日志和binlog日志协调工作  

      说到这里就要谈谈两阶段提交,当会话发起commit(提交)工作时,先进行存储引擎的prepare(准备)工作,这里的prepare工作只是在对应的Redo日志上打上prepare标记,随后会写入binlog并执行fsync(系统调用,对binlog执行磁盘同步),最后再Redo日志记录上打上commit标记表示记录以提交完成。  

     

    6.Redo日志的一些参数说明:

    innodb_log_file_size            ##每个redo log日志大小(对应磁盘上的文件就是ib_logfile0/ib_logfile1  ...)
    innodb_log_group_home_dir    ##这个是redo log日志的存在磁盘的目录,默认是数据目录下
    innodb_log_files_in_group       ##指定日志文件组中重做日志文件的数量,默认是2
    innodb_flush_log_at_trx_commit = n  ##双一之一,表示redo log flush 磁盘机制,与后面的sync_binlog会细说
    innodb_mirrored_log_groups          ##指定了日志镜像文件组的数量,默认为1

        

         

  • 相关阅读:
    AGC012
    AGC010
    AGC010
    AGC010
    AGC010
    BZOJ2120
    python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】
    python_way ,day7 面向对象 (初级篇)
    python_way.day7 模块(configparser,xml,shutil,subprocess)、面向对象(上)(创建类,类的构成,函数式编程与面向对象编程的选择,类的继承)
    python_way ,day5 模块,模块3 ,双层装饰器,字符串格式化,生成器,递归,模块倒入,第三方模块倒入,序列化反序列化,日志处理
  • 原文地址:https://www.cnblogs.com/zmc60/p/14942824.html
Copyright © 2020-2023  润新知