MYSQL执行一条update语句,期间发生了什么

  1. 客户端先通过连接器建立连接,连接器自会判断用户身份;

  2. 因为这是一条 update 语句,所以不需要经过查询缓存,但是表上有更新语句,是会把整个表的查询缓存清空的,所以说查询缓存很鸡肋,在 MySQL 8.0 就被移除这个功能了;

  3. 解析器会通过词法分析识别出关键字 update,表名等等,构建出语法树,接着还会做语法分析,判断输入的语句是否符合 MySQL 语法;

  4. 预处理器会判断表和字段是否存在,同时将*替换成所有的列值;

  5. 优化器确定执行计划,因为 where 条件中的 id 是主键索引,所以决定要使用 id 这个索引;

  6. 执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取 id = 1 这一行记录:

    • 如果 id=1 这一行所在的数据页本来就在 buffer pool 中,就直接返回给执行器更新;

    • 如果记录不在 buffer pool,将数据页从磁盘读入到 buffer pool,返回记录给执行器。

  7. 执行器得到聚簇索引记录后,会看一下更新前的记录和更新后的记录是否一样:

    • 如果一样的话就不进行后续更新流程;

    • 如果不一样的话就把更新前的记录和更新后的记录都当作参数传给 InnoDB 层,让 InnoDB 真正的执行更新记录的操作;

  8. 开启事务, InnoDB 层更新记录前,首先要记录相应的 undo log,因为这是更新操作,需要把被更新的列的旧值记下来,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面,不过在内存修改该 Undo 页面的时候,也需要将修改的信息保存到 redo log中,以便持久化。

  9. InnoDB 层开始更新记录,会先更新内存(同时标记为脏页),然后将记录写到 redo log 里面,这个时候更新就算完成了。为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘(比如redolog的持久化文件写满,此时mysql会阻塞,将脏页数据刷新到磁盘,然后清空redolog持久化文件)。这就是 WAL 技术,MySQL 的写操作并不是立刻写到磁盘上,而是先写 redo 日志,然后在合适的时间再将修改的行数据写到磁盘上。

  10. 至此,一条记录更新完了。

  11. 在一条更新语句执行完成后,然后开始记录该语句对应的 binlog(service层),此时记录的 binlog 会被保存到 binlog cache,并没有刷新到硬盘上的 binlog 文件,在事务提交时才会统一将该事务运行过程中的所有 binlog 刷新到硬盘。

  12. 事务提交(为了方便说明,这里不说组提交的过程,只说两阶段提交):

    • prepare 阶段:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘;

    • commit 阶段:将 binlog 刷新到磁盘,接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(将事务设置为 commit 状态后,刷入到磁盘 redo log 文件);

    • 通过上面保证了两个日志文件的一致性,数据恢复时读取redolog时如果是prepare状态,会拿着里面的XID去binlog中寻找,如果不存在说明后续的binlog持久化失败,为了保证两者的一致性redolog会回退。

  13. 至此,一条更新语句执行完成。

相关推荐
Fleshy数模3 小时前
CentOS7 安装配置 MySQL5.7 完整教程(本地虚拟机学习版)
linux·mysql·centos
az44yao4 小时前
mysql 创建事件 每天17点执行一个存储过程
mysql
秦老师Q5 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
橘子136 小时前
MySQL用户管理(十三)
数据库·mysql
Dxy12393102166 小时前
MySQL如何加唯一索引
android·数据库·mysql
我真的是大笨蛋6 小时前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怣506 小时前
MySQL数据检索入门:从零开始学SELECT查询
数据库·mysql
人道领域7 小时前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
千寻技术帮8 小时前
10404_基于Web的校园网络安全防御系统
网络·mysql·安全·web安全·springboot
spencer_tseng8 小时前
MySQL table backup
mysql