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

posted @ 2020-09-03 15:56  队长别开枪 是我  阅读(944)  评论(1编辑  收藏  举报