• InnoDb存储引擎执行流程


    缓冲池 buffer pool

    • 会把一些磁盘上的数据加载到该内存当中
    • 查询数据的时候不从磁盘查,从该内存里查

    undo log

    • 逻辑日志,可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录
    • 用于数据回滚
    • 实现mvcc

    redo log

    • 存储引擎层日志
    • 物理日志(类似于“对哪个数据页中的什么记录,做了个什么修改”)
    • 记录对数据做了什么修改,防止已提交事务的数据丢失。因为数据不是实时刷盘的,数据是在buffer pool当中,如果数据库宕机了并且buffer pool中的数据还没有刷盘,修改过的数据就丢失了,redo log解决这一问题
    • redo log buffer是redo log的缓冲区,数据做了什么修改,首先会写入到redo log buffer中,再刷盘写入redo log中

    binlog

    • 归档日志,属于mysql server层,不属于存储引擎层
    • 逻辑性日志(类似于“对users表中的id=10的一行数据做了更新操作,更新以后的值是什么”)

    事务还没有提交,mysql宕机了怎么办?

    • 事务没有提交,mysql宕机,buffer pool和redo log buffer中的数据都会丢失,数据库返回异常,提示事务失败
    • 磁盘上的数据没有任何变化,不影响

    redo log刷盘策略

    • 当提交事务的时候,redo log buffer里的数据会根据一定规则刷到磁盘上
    • 通过innodb_flush_log_at_trx_commit参数来配置
      • 0 提交事务的时候,不立即把 redo log buffer 里的数据刷入磁盘文件的,而是依靠 InnoDB 的主线程每秒执行一次刷新到磁盘。此时可能你提交事务了,结果 mysql 宕机了,然后此时内存里的数据全部丢失
      • 1 提交事务的时候,就必须把 redo log 从内存刷入到磁盘文件里去,只要事务提交成功,那么 redo log 就必然在磁盘里了
      • 2 提交事务的时候,把 redo 日志写入磁盘文件对应的 os cache 缓存里去,而不是直接进入磁盘文件,可能 1 秒后才会把 os cache 里的数据写入到磁盘文件里去。此时mysql宕机,数据不会丢失;如果机器宕机,数据会丢失

    binlog刷盘策略

    • 当提交事务的时候,binlog也会刷到磁盘上去
    • 通过sync_binlog参数来配置
      • 0 默认值。事务提交后,将二进制日志写入了操作系统缓冲,若操作系统宕机则会丢失部分二进制日志
      • 1 事务提交后,将二进制文件写入磁盘并立即执行刷新操作,相当于是同步写入磁盘,不经过操作系统的缓存

    执行一条更新sql语句,存储引擎执行流程

    1. 把该行数据从磁盘加载到buffer pool中
    2. 对该行数据进行加锁
    3. 写undo log
    4. 在buffer pool当中更新数据
    5. 把所作的修改写入到redo log buffer当中
    6. 准备提交事务redolog刷盘
    7. 准备提交事务binlog刷盘
    8. 把binlog的文件名和位置写入commit标记,commit标记写入redolog中,事务才算提交成功;否则不会成功


    commit标记的意义

    • redo log刷盘成功,binlog还没刷盘,数据库宕机,没有commit标记写到redo log中,事务判定为失败。因为redolog中有这次更新日志,binlog中没有这次更新日志,会出现数据不一致问题
    • redo log刷盘成功,binlog刷盘成功,commit标记还没来得及写入redo log中,数据库宕机,同样判定事务提交失败
    • commit写入redo log,才能判定事务成功;因为此时,redo log中有这次更新记录,binlog也有这次更新记录,redo log和binlog保持了一致

    内存(buffer pool)中更新过脏数据什么时候刷盘?

    • 后台io线程有时间会把内存buffer pool中更新过的脏数据(因为更新过,和磁盘上的数据不一样,所以叫脏数据)刷回到磁盘上,哪怕这时候mysql宕机,也没有关系,可通过redo log和binlog恢复数据到内存中,io线程有时间再把数据刷盘


    执行更新sql语句存储引擎执行流程总结

    • 执行阶段
      • 数据加载到内存,写undo log,更新内存中数据,写redo log buffer
    • 事务提交阶段
      • redo log和binlog刷盘,commit标记写入redo log中
    • 最后
      • 后台io线程随机把内存中脏数据刷到磁盘上



    文章和图片参考 救火队长mysql

  • 相关阅读:
    STL与泛型编程-练习2-GeekBand
    HashSet
    JAVA集合
    分布式锁1 Java常用技术方案
    JAVA 锁
    JAVA多线程二
    JAVA多线程一
    Redis pipeline and list
    mongo 安装
    Intersection of Two Arrays
  • 原文地址:https://www.cnblogs.com/wasitututu/p/13608045.html
Copyright © 2020-2023  润新知