查询SQL执行流程
一条查询SQL的执行过程
select * from tb_user where id = 1;
SQL执行流程:
- 客户端与 MySQL Server建立连接,客户端和服务端都使用池化技术来管理连接
- 服务端为每个连接分配一个线程,通过线程来监听客户端的请求,当客户端发起一条SQL请求时,服务端线程接收SQL请求,交给SQL接口处理
- SQL接口将SQL语句交给查询解析器处理
- 查询解析器进行词法分析,分析SQL是否符合数据库规则,select,insert等关键字是否正确,再进行语法分析,校验SQL语句是不是合法,如果不合法会报错,合法的话最后会生成一颗解析树
- 查询优化器将解析树转化为执行计划,一条复杂的select语句,有很多种执行方式,优化器会选择它认为最优的执行计划。
- 执行器有了执行计划后,就可以通过执行器按照计划中的步骤,调用存储引擎接口操作数据了
- 最后在存储引擎中操作内存或磁盘中的数据
MySQL中存储引擎有InnoDB,MyISAM,Memory,默认为 InnoDB。
update 语句执行流程
id | name | age |
---|---|---|
1 | muskmelon | 18 |
2 | 李四 | 22 |
有这样一张表,表里有2条数据,当我们执行一条update语句的时候,InnoDB中的执行流程如下图所示:
update tb_user set name = '张三' where id = 1;
update更新流程
(1)先从缓冲池中查找 id = 1 的数据,如果找不到则读取磁盘数据,然后加载到缓冲池中,同时还会对这行数据进行加锁
(2)将 id = 1,name = muskmelon 的数据写入 undo log,用于回滚
(3)更新缓冲池中的数据 id = 1,name = 张三,此时缓冲池中的数据属于脏数据,因为数据还未刷入磁盘,磁盘上的 name = muskmelon
(4)提交事务,将缓冲池的数据写入 redo log
(5)通过参数 innodb_flush_log_at_trx_commit
来控制redo log是否需要刷盘:
- 0:事务提交后,每隔
innodb_flush_log_at_timeout
时间写 os cache 且刷盘,速度最佳,但会丢失数据 - 1:事务提交后,写os cache 且刷盘,数据0丢失
- 2:事务提交后,先写到 os cache ,每隔
innodb_flush_log_at_timeout
时间进行刷盘,效率较直接刷盘高一些,但仍然会存在数据丢失情况
(6)写binlog日志,通过参数sync_binlog
来配置是否需要刷盘
- 0:不刷盘,写入os cache,由操作系统决定何时去刷盘
- 1:刷盘,写入 磁盘,当事务提交时,刷盘
- N:当N 个事务提交时,刷盘
(7)向 redo log中写入binlog文件位置和 commit 标记,保证 redo log 与 binlog数据一致,至此整个事务才算真正的提交了。
(8)存储引擎内部通过IO线程将缓冲池中的数据刷入磁盘