在关系型数据库(如 MySQL、PostgreSQL 等)中,执行一条UPDATE
语句的过程涉及多个步骤,涉及到数据库的查询处理、事务管理、日志记录、数据存储等多个方面。下面详细描述一条UPDATE
语句在进入数据库后的执行过程。
1.SQL 语句解析
步骤 1:SQL 解析
首先, UPDATE
语句会经过数据库的SQL 解析器,其目的是对 SQL 语句进行语法分析和语义分析。数据库会检查UPDATE
语句的结构是否符合 SQL 的语法规范,并且确定UPDATE
语句中的表、字段、条件是否存在。解析器会将 SQL 语句转换成一个查询树(query tree)或查询计划(query plan),它是数据库对执行该语句的内部表示。
步骤 2:查询优化
SQL 查询会进入查询优化器,优化器会分析不同的执行路径(如索引扫描、全表扫描等),并选择一个最优的执行计划。优化器考虑多个因素,如表的大小、索引的使用、统计信息等,以选择最有效的执行方式。 对于 UPDATE
语句,优化器需要决定如何高效地定位需要更新的记录,并确定使用何种方法来修改数据。
2.执行计划生成与执行
步骤 3:执行计划生成
基于优化器选择的执行计划,数据库生成一个具体的执行步骤。这可能包括: - 定位数据
:确定如何根据 WHERE
子句定位需要更新的记录(可能是基于索引或全表扫描)。 - 计算结果
:根据 SET
子句,确定需要更新的字段及其新的值。
- 定位数据
步骤 4:锁定相关行
在进行数据修改前,数据库会对符合 WHERE
子句条件的行进行锁定。锁定的目的是确保在事务执行期间,这些数据不会被其他事务修改(保证事务的隔离性)。锁定的类型通常是行锁(在支持行级锁的数据库中,如 InnoDB)或者表锁(对于一些简单的存储引擎,可能会使用表级锁)。
步骤 5:读取数据(缓存/磁盘)
数据库会读取满足条件的行,并将其加载到缓冲区。对于较小的表,这个过程可能在内存中完成;对于较大的表,数据库可能需要从磁盘读取数据。 如果数据库使用缓存(如 MySQL 的 InnoDB 存储引擎有缓冲池),更新操作会在内存中的数据页(page)上进行,而不是直接在磁盘上操作。
3.事务日志记录
步骤 6:生成 Undo Log 和 Redo Log
在数据库执行UPDATE
语句时,两个关键的日志文件:Undo Log 和Redo Log 会被更新。
- Undo Log
:在执行数据更新前,数据库会记录该行的原始数据(即更新前的值)。这为事务回滚提供了信息。即使事务没有提交,如果发生了回滚,Undo Log 会使得数据恢复到原始状态。 - Redo Log
:在执行数据修改时,数据库会将更新的内容记录到 Redo Log 中。Redo Log 主要用于在数据库崩溃后恢复已提交的事务。它记录的是事务修改后的数据(即数据页的实际内容)。
4.更新数据
步骤 7:执行数据修改
数据库会修改内存中的数据页或数据记录,按照 SET
子句的要求更新字段的值。此时,数据库修改的数据页已经改变,数据从缓存或内存中更新。如果数据不在缓存中,数据库会将其从磁盘读取到内存,然后进行更新操作。
5.写入日志
步骤 8:写入日志
在 InnoDB 或类似的存储引擎中,事务的更改并不会立即写入磁盘。首先,修改的内容会被写入内存中的数据页,并且相关的修改会记录到Redo Log 中。Redo Log 确保即使数据库崩溃,事务也能被恢复。 完成 UPDATE
操作后,undo log 和redo log 会被写入日志文件,保证数据库的持久性(Durability)。
6.提交事务
步骤 9:事务提交与提交确认
如果 UPDATE
语句属于一个事务,当该事务成功执行完后,会执行commit
操作。commit
会使得所有修改在数据库中持久化。在提交时, redo log
会确保即使系统崩溃,所有提交的数据都能恢复。undo log
会被丢弃,表示事务已经完成,回滚不再需要。
7.更新磁盘数据(写回)
步骤 10:数据刷盘
数据最终会从内存中的缓冲区被写入磁盘,这个过程通常是延迟的,采用写时复制(Write-Ahead Logging) 或脏页刷新 等技术。 数据页会在适当的时机(通常是缓冲区满了或事务提交时)被写回磁盘。
8.二进制日志(Binlog)
步骤 11:记录到 Binlog
如果数据库启用了二进制日志( binlog
),UPDATE
语句也会被记录到binlog
中。binlog
记录了数据库的每一次修改,通常是通过事件日志 或行日志 记录。binlog
主要用于数据复制和增量备份,确保数据可以被同步到从库或恢复到某个时间点。
总结
一条UPDATE
语句在进入数据库后,会经历以下几个主要步骤:
- SQL 解析
:数据库检查语法和语义,生成执行计划。 - 执行计划生成与执行
:查询优化器选择最优路径,数据库锁定数据行并读取相关数据。 - 日志记录
:生成 Undo Log 和 Redo Log,确保事务的原子性、一致性、持久性。 - 数据更新
:修改内存中的数据页(或缓存中的数据)并记录修改。 - 事务提交
:事务提交时,日志同步写入,确保数据持久化。 - 数据刷盘
:将修改写回磁盘,完成最终数据更新。 - 二进制日志(Binlog)记录
:如果启用了 binlog
,记录该更新操作,以支持数据复制和增量备份。
在整个过程中,事务日志(如 Undo Log 和 Redo Log)是确保数据库在崩溃或故障后能够恢复的关键,而二进制日志则用于数据复制和备份恢复。
文章转载自解压泡泡糖,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




