sql更新是如何执行的?

update from set a = 1 where id = 1

首先看一下一张图(图片来自 sql查询是如何执行的?)

image.png

和查询类似,也会走同样的逻辑。

  1. 创建连接。
  2. 清除缓存。
  3. 分析器 分析语法,检查表和字段是否存在。
  4. 优化器,决定是否使用索引,使用哪一个索引。
  5. 执行器。主要区别在这一层,下面说说我理解的具体区别。

与查询流程不同的是,更新涉及到redo_log (重做日志) 和 binlog(归档日志)

redo log

如果更新数据直接修改磁盘数据,会首先找到磁盘中的数据,然后在修改磁盘中的数据,io成本会很高。所以mysql更新不会直接修改逻辑数据,而是先写到内存中,然后等mysql空闲之后,会同步到硬盘。

  1. 作用在存储引擎上,innodb 特有的。
  2. redo log 大小是固定的。类似一个环,每次写满之后会强制刷新,从头开始写。
  3. redo log 会保证即使数据库发生异常,数据也不会丢失。
  4. 物理日志,记录了在哪个数据页上的修改

binlog

作用在service层,是mysql的日志,所有存储引擎都可以使用。记录了所有增删改的逻辑日志。

记录方式 statement 记录sql语句 row 记录每一行数据的改动,mixed(混合模式) mysql会根据具体的sql来决定按照什么方式进行记录

执行器的执行流程

update t set a=a+1 where id=1;
  1. 调用存储引擎接口,找到id=1这一条记录。如果数据在内存中直接返回,否则先从磁盘中读到内存,然后返回
  2. 执行器拿到结果,进行+1操作,再调用存储引擎接口写入新数据。
  3. 存储引擎将这行数据更新到内存,同时记录redo log(perpare) 然后返回成功
  4. 执行器生成binlog,把binlog写入磁盘。
  5. 调用引擎提交事务,把redo log 改成提交状态(commit)。更新完成
image.png

两阶段提交

上面redo log 2次写入被称为两阶段提交。

redo log 保证了及时异常重启,也会把数据刷新到磁盘中。binlog主要适用于数据备份的。

目的:因为redo log 和binlog 是2个完全不同的东西,一个是存储引擎实现的一个是数据库本身实现的。所以为了保证redo log 和binglog 的一致性,引入了两阶段提交。

uodo log 只是为了回滚使用,比如把name=‘a’ 修改为name = ‘b’ ,那么undo日志就会用来存放name=’a’的记录,如果这个修改出现异常,可以使用undo日志来实现回滚操作,保证事务的一致性。

你可能感兴趣的:(sql更新是如何执行的?)