Skip to content

Commit dcb8a3b

Browse files
authored
Merge pull request #2776 from Ka1Yann/patch-1
Update how-sql-executed-in-mysql.md
2 parents f50a2ea + 38c9664 commit dcb8a3b

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

docs/database/mysql/how-sql-executed-in-mysql.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,10 @@ update tb_student A set A.age='19' where A.name=' 张三 ';
105105

106106
我们来给张三修改下年龄,在实际数据库肯定不会设置年龄这个字段的,不然要被技术负责人打的。其实这条语句也基本上会沿着上一个查询的流程走,只不过执行更新的时候肯定要记录日志啦,这就会引入日志模块了,MySQL 自带的日志模块是 **binlog(归档日志)** ,所有的存储引擎都可以使用,我们常用的 InnoDB 引擎还自带了一个日志模块 **redo log(重做日志)**,我们就以 InnoDB 模式下来探讨这个语句的执行流程。流程如下:
107107

108-
- 先查询到张三这一条数据,不会走查询缓存,因为更新语句会导致与该表相关的查询缓存失效
108+
- 先查询到张三这一条数据,不会走查询缓存,因为查询缓存的设计规则就是只服务于查询类语句
109109
- 然后拿到查询的语句,把 age 改为 19,然后调用引擎 API 接口,写入这一行数据,InnoDB 引擎把数据保存在内存中,同时记录 redo log,此时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,随时可以提交。
110-
- 执行器收到通知后记录 binlog,然后调用引擎接口,提交 redo log 为提交状态。
110+
- 执行器收到通知后记录 binlog,然后清空该表的查询缓存。此时清空能保证后续的 SELECT 不会读到旧缓存 —— 因为事务马上就要最终提交,数据即将变成最新状态,缓存失效的时机刚好匹配数据的实际更新。
111+
- 执行器调用引擎接口 ,提交 redo log 为 commit 状态。
111112
- 更新完成。
112113

113114
**这里肯定有同学会问,为什么要用两个日志模块,用一个日志模块不行吗?**

0 commit comments

Comments
 (0)