mysql:一条SQL更新语句是如何执行的

如下一条更新sql:

UPDATE "public"."t_param_config" SET "id"='12', "param_key"='isOpenRedis', "param_value"='0', "param_desc"='是否启动Redis:0开启|1关闭', "status"='1' WHERE ("id"='12');

1、首先还是连接器连接数据库
2、分析器通过词法和语法解析知道这是一条更新语句
3、优化器决定是否使用索引
4、执行器具体执行。

1、重要的日志模块:redo log-物理日志

1、在mysql中,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录然后再更新,那么整个IO成本、查找成本都很高。为了解决这个问题,mysql的设计者使用到了WAL技术。WAL即全称是Write-Ahead Logging,该技术的关键点就是先写日志,再写磁盘。具体来说,当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到redo log里面,并更新内存,这个时候更新就算完成了。同时InnoDB引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新操作往往是在系统比较空闲的时候做。

2、InnoDB的redo log的固定大小的,比如可以配置为一组4个文件,每个文件的大小为1GB,如下图所示,write pos是当前记录的位置,一边写一边后移,写到第3个号文件末尾后就回到0号文件开头。checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。(这里的write pos可以理解为记录日志到内存,checkpoint可以理解为将内存中的数据写入到磁盘。)
在这里插入图片描述

2、重要的日志模块:binlog-逻辑日志

1、binlog是逻辑日志,记录的是这个语句的原始逻辑
2、redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

3、更新流程

1、执行器先找引擎取ID=2这一行。ID是主键,引擎直接用树搜索找到这一行。如果ID=2这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
2、执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
3、引擎将这行新数据更新到内存中,同时将这个更新操作记录到redo log里面,此时redo log处于prepare状态。然后告知执行器执行完成了,随时可以提交事务。
4、执行器生成这个操作的binlog,并把binlog写入磁盘。
5、执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成提交(commit)状态,更新完成。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_28893679/article/details/89353169