zoukankan      html  css  js  c++  java
  • InnoDB redo

    一、REDO简介

    • redo log用于记录除了 SELECT的所有操作。
    • 重做日志作用是:当崩溃恢复期间用于前滚已经提交的数据,回滚未提交的数据。
    • MySQL以循环方式写入重做日志文件。
    • 重做日志的增加以LSN值表示。
    • 切换redo log的时候发生checkpoint,触发脏页的刷新
    • 默认情况下,innodb会创建2组大小均为5M的REDOLOG,分别为ib_logfile0、ib_logfile1,保存在datadir指定的路径下。相关的参数有下列几个
      • innodb_log_group_home_dir:指定redolog保存路径,默认在datadir指定的路径下
      • innodb_log_file_size:指定日志文件的大小,默认是5M,最大512G.该参数会影响检查点的执行频率,以及故障的恢复时间。一般来说,日志设置的越大,检查点执行的频率就越低,但是如果在这期间发生故障,启动的时候就会越长。
      • innodb_log_files_in_group:指定日志文件组的数量
      • innodb_fast_shutdown
        • 0:等到会话结束,事务结束,缓冲区的数据刷新到磁盘,类似shutdown normal
        • 1:关闭会话终止连接,将已提交的刷新到数据文件,未提交的回滚。类似shutdown immediate
        • 2:忽略所有操作,直接关闭数据,类似shutdown abort

         以上参数不支持动态修改

    • 触发 log buffer 刷新到 redo log的条件
      • commit,innodb_flush_log_at_trx_commit参数控制
        • 0:每秒刷新
        • 1:commit 的时候刷新到磁盘
        • 2:commit时刷新到系统的buffer中
      • redo log thread:1s,可以通过 innodb_flush_log_at_timeout 参数控制
      • redo log buffer:1/2

    二、redo log 跟 binlog

    2.1 redo log 跟 binlog的区别

    第一:记录的内容不同

    binlog记录数据的改变信息

    redo log记录的是页的改变信息

     

    第二:记录的时间不同

    binlog记录commit后的操作

    redolog记录事务发起后的操作

     

    第三:文件使用方式不同

    binlog写完会生成新的文件

    redolog最后一个文件写完,会覆盖第一个文件

     

    第四:作用不同

    binlog可以作为恢复数据,主从搭建

    redolog作为异常宕机后 Innodb实例会崩溃恢复

     

    2.2 redo log 跟 binlog的关系

    MySQL两阶段提交过程:

    • 准备过程:InnoDB 层写 prepare log
      • 写的还是 redo file
      • 写入的是 xid (事物 id)
    • 提交过程:分为2个步骤
      • 将binlog cache 中的事务写入 binlog 文件
      • 再在redo log中做一个事务提交的标记,并把 binlog 写成功的标记页一并写到 redo log文件中

     

    场景一

    准备阶段,redo log刷新到磁盘,但是binlog写盘前发生了MySQL实例crash。这时,即使redo log写盘成功了,但由于binlog未写入成功,也是需要回滚

    场景二

    提交阶段,binlog写盘成功了,这时候MySQL实例crash。这是binlog已经确保写成功了,重启MySQL的时候,检测到redo中和binlog中都有xid。那么,只需要让redo 强制提交就可以了

     

    三、组提交

    组提交主要是为了解决写日志时频繁刷磁盘的问题。

    5.5 时只支持 redo 组提交,5.6之后支持 binlog 组提交,5.6之后的大并发性能问题比5.5好的一个原因

    3.1 redo 组提交

    事务提交时会进行两个阶段的操作:

    1. 将日志写入 redo log buffer
    2. 从 redo log buffer 写入磁盘

    在没有 redo 组提交之前,步骤 2 相对于 步骤 1 的速度是较慢的。

    出现 redo 组提交之后,多个事物 redo log 刷盘动作合并,减少 IO 调用。它的原理是:

    redo log 中的 LSN 是单调递增的,每个事务的产生,都会获取到最大的 LSN。假设事务 trx1,trx2,trx3 对应的 LSN 分别是 LSN1,LSN2,LSN3,如果 trx3 先获取到 log_mutex 进行落盘,他就顺便可以把 LSN1,LSN2,LSN3 这段日志也进行刷盘。

    但是,redo 组提交也只限于没有开启 binlog 的情况下,当开启了 binlog 之后,为了保证 redo 和 binlog的写入一致性。就涉及到一个两阶段提交:

    prepare 阶段,innodb刷新 redo log,并将 UNDO 设置为 prepare 状态

    commit 阶段,binlog 刷盘,最后设置 commit 状态。

    对于多个事务的组提交,一个关键是保证事务在redo log和binlog中的顺序一致。上述的2PC并不能保证这一点。所以在 5.5 的时候就引入了 prepare_commit_mutex,见下图

    prepare 阶段,持有 prepare_commit_mutex, innodb刷新 redo log,并将 UNDO 设置为 prepare 状态

    commit 阶段,binlog 刷盘,最后设置 commit 状态。释放 prepare_commit_mutex。

    持有 prepare_commit_mutex 期间,其他事务不能写 redo。这样就保证了串行执行。同时组提交失效,在 5.6 之后,为了解决这个问题,引入了 binlog group commit

     

    3.2 binlog 组提交

    binlog 组提交 引入了队列机制保证 innodb commit 顺序与 binlog 落盘顺序一致,并将事务分组,组内的 binlog 刷盘动作交给一个事务进行。binlog 组提交将提交分为了3个阶段

    1. FLUSH 阶段
      1. 持有 lock_log mutex (leader 持有,followr 等待)
      2. 获取队列中的一组 binlog (队列中的所有事务)
      3. 将 binlog buffer 到 I/O cache
      4. 通知 dump 线程 dump binlog
    1. SYNC 阶段
      1. 释放lock_log mutex,持有 lock_sync mutex(leader 持有,follower 等待)
      2. 将一组 binlog落盘(sync 动作,假设 sync_binlog 为1)
    1. COMMIT阶段
      1. 释放 lock_sync mutex,持有 lock_commit mutiex(leader持有,follower等待)
      2. 遍历队列中的事务,逐一进行 innodb commit
      3. 释放 lock_commit mutex
      4. 唤醒队列中等待的线程

     

    3.3 组提交相关参数

    binlog_group_commit_sync_no_delay_count:等待一组里面有多少事物我才提交

    binlog_group_commit_sync_delay:等待多少时间后才进行组提交

     

    参考书籍:《MySQL技术内幕》、《MySQL王者晋级之路》

    参考博客:https://www.cnblogs.com/cchust/p/4439107.html

  • 相关阅读:
    Net基础篇_学习笔记_第十二天_面向对象继承(命名空间 、值类型和引用类型)
    Net基础篇_学习笔记_第十一天_面向对象(练习)
    js判断客户端是pc还是移动端
    swoole_table
    Master Reactor Manager Worker TaskWorker(Task)
    阻塞,非阻塞,同步,异步
    进程,线程与协程
    swoole 安装与简单应用
    laravel 简单应用 redis
    ubuntu 设置固定IP
  • 原文地址:https://www.cnblogs.com/ziroro/p/9833649.html
Copyright © 2011-2022 走看看