一. 概述
一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎. 其实,查询语句的那一套流程,更新语句也是同样会走一遍。
- 连接器,连接数据库
- 缓存失效:一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表 T 上所有缓存结果都清空.这也就是不建议使用查询缓存的原因。
- 分析器会通过词法和语法解析知道这是一条更新语句
- 优化器决定要使用什么索引等
- 执行器负责具体执行,找到这一行,然后更新
查询流程不一样的是,更新流程还涉及到几个重要日志,除了前边事务隔离提到的undolog, 还有两个重点 redo log(重做日志)和 binlog(归档日志)
二. 执行器具体执行步骤
执行流程
1.执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页(page)本来就在内存中,就直接返回给执行器;否则,需要先从磁盘将ID=2 这一行所在的数据页读入内存,然后再返回。 注意加载缓存的单位是“page”,而非行。
- 记录undo-log日志回滚链,具体结构可以参考我之前的文章:
https://www.jianshu.com/p/2b1800e3218b
- 调用执行引擎更新内存数据。
- 发起写Redo-log 日志。
- 讲修改操作写到redo-log buffer中,日志属于prepare状态,此时就告诉执行器可以递交事务了。此时整个事务处于非commit状态,但是也存在一些场景讲buffer写入磁盘,具体见下一章。
- 执行器生成这个操作的 binlog,并把 binlog 写入磁盘
- 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成.---- 注意这里可能日志未持久化到磁盘。
- 在适当的时机,内存会将更新的数据记录到磁盘。