简述查询语句执行流程
举个例子,查询语句如下:
select * from user where id > 1 and name = 'zxb';
- 首先检查权限,没有权限则返回错误;
- MySQL8.0以前会查询缓存,缓存命中则直接返回,没有则执行下一步;
- 词法分析和语法分析。提取表名、查询条件,检查语法是否有错误;
- 两种执行方案,先查 id > 1 还是 name = 'wzx' ,优化器根据自己的优化算法选择执行效率最好的方案;
- 校验权限,有权限就调用数据库引擎接口,返回引擎的执行结果。
简述更新语句执行过程
举个例子,更新语句如下:
update user set name = 'zxb' where id = 1;
- 先查询到 id 为1的记录,有缓存会使用缓存。
- 拿到查询结果,将 name 更新为wzx,然后调用引擎接口,写入更新数据,innodb 引擎将数据保存在内存中(并不会直接更新外存,而是缓存在InnoDB的 Change Buffe中),同时记录 redolog (确保持久性),此时 redo log 进入 prepare 状态。
- 执行器收到通知后记录 binlog ,然后调用引擎接口,提交 redo log 为 commit 状态。
- 更新完成。
为什么记录完 redo log ,不直接提交,而是先进入 prepare 状态?
假设先写
redo log
直接提交,然后写
binlog
,写完
redo log
后,机器挂了,
binlog
日志没有被写入,那么机器重启后,这台机器会通过 redo log
恢复数据,但是这个时候
binlog
并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。