自学内容网 自学内容网

MySQL update 一条语句的过程

查询阶段

  1. 连接器:建立连接,校验用户身份
  2. 解析 SQL:通过解析器对 SQL 语句进行词法分析、语法分析,构建语法树。
  3. 执行 SQL:
    1. 预处理阶段:检查表或字段是否存在;将 * 扩展为表上的所有列。
    2. 优化阶段:优化器选择查询成本最小的执行计划;
    3. 执行阶段:根据执行计划执行 SQL 语句,获取记录并更新。

更新阶段

  1. 执行器调用存储引擎的接口,通过执行计划获取符合条件的记录:
    • 如果记录所在数据页在 buffer pool 中,就直接返回给执行器更新;
    • 如果记录不在 buffer pool,先将数据页从磁盘读入到 buffer pool,再返回记录给执行器。
  2. 执行器得到记录后,判断更新前后的记录是否一样:
    • 如果一样就不进行后续流程;
    • 不一样就把更新前的记录和更新后的记录都当作参数传给 InnoDB 层,让 InnoDB 执行更新记录的操作;
  3. 开启事务,更新记录前要先记录相应的 undo log,undo log 会写入 buffer pool 的 undo 页面,写入 undo 页面前需要先记录修改 undo 页面的 redo log。所以这里的流程是:先记录修改 undo 页面的 redo log ,然后再将 undo log 写入到 undo 页面。
  4. 写完 undo 页面后 InnoDB 开始更新记录,先将新的记录写到 redo log 里,再修改 buffer pool 中的记录,同时标记为脏页。InnoDB 会先将 redo log 写入到磁盘,再择机将脏页落盘(WAL 思想)。
  5. 至此,一条记录更新完了。
  6. 记录更新完后,会记录该语句对应的 binlog,事务提交会统一将该事务运行过程中所有 binlog 刷新到硬盘。
  7. 事务提交(两阶段提交):
    • prepare 阶段:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘。
    • commit 阶段:将 binlog 刷新到磁盘,接着调用存储引擎的提交事务接口,将 redo log 设置为 commit。
  8. 至此,一条更新语句执行完成。

补充

redo log 刷盘时机

  • redo log 不是直接写入到磁盘的,也是先写入到 redo log buffer(用户空间内存)中。
  • redo log buffer 在 mysql 正常关闭时 | 每隔一秒 | redo log buffer 中记录写入量大于一半内存时会直接落盘。
  • 事务提交时,可以通过参数控制是否直接落盘还是先写入到 redo log 文件(内核空间内存)中。

buffer pool 刷盘时机

脏页写入磁盘的操作与事务提交是解耦的。

  • 后台线程定期刷盘;
  • MySQL 正常关闭
  • 手动刷新;
  • Redo Log Buffer 满了;
  • Buffer Pool 空间不足。
  • 定期会触发 Checkpoint 操作,强制将一定数量的脏页刷盘,以减少系统崩溃时需要恢复的数据量。

binlog 刷盘时机

事务执行过程中会先把日志写到 binlog cache 中,事务提交时再把 binlog cache 写到 binlog 文件(内核空间内存)中。通过参数可以控制执行 fsync 的时机(从内核空间内存到磁盘)。

更多补充:MySQL 的 undo log,redo log,binlog 总结


原文地址:https://blog.csdn.net/qq_43710228/article/details/142435736

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!