redo log

redo log即重做日志文件,用于记录事物操作的变化,记录的是数据修改后的值,不管事务是否提交都会记录下来,保证数据的完整性
redo log写的方式:

  • 顺序写—第一个文件写满之后,会按顺序写下一个文件
  • 循环写—写满最后一个文件之后,会重新从都一个文件开始写

写满日志文件会产生切换操作,并执行checkpoint,触发脏页刷新。

当mysql数据库重启时,如果参数文件的redo log值与当前redo log值不一致,会把现有的redo log删除,并按照参数文件设置的大小重新生成redo log文件。在此之前,数据会先写入 redo log buffer

redo log buffer刷到磁盘的条件:

  1. innodb_flush_log_at_trx_commit参数:
    • 0—性能最好,不太安全—每次事务提交不会触发redo log thread将日志缓冲中的数据写入 redo log 文件
    • 1—安全,但是数据库性能慢—每次事务提交时,触发redo log thread将日志缓冲中的数据写入 redo log 文件,并flush到磁盘
    • 2—中规中矩—每次事务提交时,触发redo log thread将日志缓冲中的数据写入 redo log 文件,但不会刷新(flush)到磁盘,该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。
  2. master thread:每秒进行刷新
  3. redo log buffer:使用超过一半的时候会触发刷新

    binlog

    mysql的二进制日志文件,以二进制方式记录了数据库上的所有改变,用于备份恢复和主从备份。

binlog cache刷新到磁盘的binlog文件的条件为sync_binlog参数,该参数有n个值:

  • 0:事务提交之后,mysql不做fsync之类的 磁盘同步指令 刷新binlog cache中的信息到硬盘,而是让 filesystem自行决定什么时候来做同步,或cache满了之后才同步到硬盘
  • n:每进行n此事务提交之后,mysql将进行一次 fsync之类的 磁盘同步指令 将binlog cache中的信息强制写入到硬盘
  • 为了安全性设置为1,最佳性能设置为0
  • 双一模式:sync_binlog=1,innodb_flush_log_at_trx_commit=1。即:每次事务提交之后,mysql会进行一次 fsync之类的 磁盘同步指令 将binlog cache中的信息强制写入到硬盘,且触发redo log thread将日志缓冲中的数据写入 redo log 文件,并flush到磁盘

    binlog和redo log异同

  1. 记录内容不同
    • binlog是逻辑日志,记录所有数据的改变信息
    • redo log是物理日志,记录所有InnoDB表数据的变化
  2. 记录内容的时间不同
    • binlog记录commit完毕之后的DML和DDL SQL语句
    • redo log记录事务发起之后的DML和DDL SQL语句
  3. 文件使用方式的不同
    • binlog不是循环使用,在写满或者实例重启之后,会生成新的binlog文件
    • redo log是循环使用,最后一个文件写满之后,会重新写第一个文件
  4. 作用不同
    • binlog可以作为恢复数据使用,主从复制搭建
    • redo log作为异常宕机或者介质故障后的数据恢复使用

      mysql两阶段提交过程

      目的是为了让两份日志之间逻辑一致,分为prepare和commit阶段
  • 准备阶段(transaction prepare):事务语句先写入redo log buffer,然后做一个事务准备标记,再将log buffer中的数据刷新到redo log
  • 提交阶段(commit):将事务产生的biglog写入文件,刷入磁盘

只要binlog写入完成,在主从环境中,都会正常完成事务
一条update语句的执行过程(update T set c=c+1 where ID=2;):
内存刷新机制(redo log&binlog) - 图1

脏页刷新条件

  1. 重做日志ib_logfile文件写满之后,在切换的过程中会执行checkpoint,会触发脏页的刷新条件
  2. 通过innodb_max_dirty_pages_pct参数的值控制。该参数是指在buffer pool中dirty page所占的百分比,达到设置的值,就会触发脏页的刷新
  3. 由innodb_adaptive_flushing参数控制。该参数影响每秒刷新脏页的数目。
  4. 刷新流程:
  • InnoDB的 redo log是固定大小的,比如可以配置一组4个文件,每个文件大小是1GB,那么这个redo log就可以记录4GB的操作。从头开始写,写到末尾又回到开头循环写:
    • write pos 是当前记录的位置,一边写一边后移,写到三号文件末尾后就回到0号文件开头
    • checkpoint是当前要擦除的位置,也是往后推移且循环的,擦除记录前要把记录更新到数据文件
    • 上面二者之间的部分是用来记录新操作的空间,如果write pos追上checkpoint,此时不能再执行新的更新,需要先停止并擦除一些记录

内存刷新机制(redo log&binlog) - 图2