MySQL更新语句执行完整流程(超详细落地版)

MySQL更新语句执行完整流程(超详细落地版) 前面介绍了mysql数据的层级结构,讲解了sql的执行过程,现针对sql的更新流程做更详细的描述。先记住终极核心链路全文背诵连接校验 → SQL解析优化 → 引擎找行 → 加锁 → 写undo → 改内存脏页 → redo prepare → 写binlog → redo commit → 事务结束释放锁 → 后台异步刷盘一、整体分层认知更新语句分为两大阶段分工极其明确MySQL Server层负责连接、解析、优化、权限、记录binlog逻辑日志InnoDB引擎层负责锁、MVCC、undo、redo、内存修改、崩溃恢复查询SQL走快照读无锁更新SQL走当前读加锁这是读写流程最大差异。二、一条 Update 完整10步执行流程以经典SQL为例update t set name zhuge666 where id 1;1. 连接层校验请求入口客户端通过TCP连接MySQL连接池完成身份认证、权限校验分配工作线程准备接收SQL。2. Server层解析 优化解析器词法语法解析校验SQL合法性生成语法树优化器选择最优索引、生成执行计划决定走主键/普通索引执行器校验读写权限调用InnoDB引擎接口正式进入写流程关键点更新语句不走查询缓存8.0已彻底废弃且更新会清空对应表缓存。3. InnoDB引擎定位数据页 加载内存根据执行计划通过索引定位数据行数据页在Buffer Pool内存中直接复用不在内存从磁盘ibd文件加载数据页到Buffer Pool4. 加锁当前读核心更新属于当前读必须加锁防止并发冲突主键等值更新加行排他锁(X锁)范围/无索引更新升级间隙锁/临键锁/表锁时机先锁数据再修改数据彻底杜绝脏写。5. 写入 Undo Log回滚MVCC修改数据之前先存旧数据。将修改前的原始行数据写入undo log通过DB_ROLL_PTR指针串联版本链作用事务失败可回滚、其他事务可快照读读旧版本不可逆规则先undo、后修改保证原子性。6. 修改内存数据页生成脏页内存Buffer Pool中的数据页被修改此时内存数据和磁盘数据不一致变成脏页。注意此时磁盘数据还没变所有修改都在内存。7. 写入 Redo LogPrepare阶段遵循WAL先写日志、后刷数据机制记录物理修改日志数据页位置偏移量修改内容写入Log Buffer后刷盘状态标记为Prepare此时 redo log 落盘保证宕机可重做数据不会丢。8. Server层写入 Binlog逻辑日志执行器在Server层记录本次更新的逻辑操作记录SQL逻辑/行变更数据生产Row模式用于主从复制、误删数据恢复binlog写入成功代表本次操作逻辑落地。9. Redo Log 二阶段提交 Commit执行2PC收尾保证 redo 与 binlog绝对一致给磁盘redo log打上commit标记MySQL判定事务正式完成宕机恢复逻辑有prepare无commit校验binlog完整性完整则重做不完整则回滚。10. 事务结束、释放锁、后台刷脏页事务提交完成立即释放行锁其他事务可竞争修改undo log 不立即删除等待无事务引用后purge线程清理后台IO线程异步刷脏页按照配置将内存数据持久化到磁盘(后面讲解日志时会详细说明)三、核心时序铁律更新语句严格顺序不可逆加锁 → 写undo → 改内存 → redo prepare → 写binlog → redo commit → 释放锁注意点不是先改数据再写日志是先日志、后数据WAL不是先写binlog再写redo是redo先prepare、binlog居中、redo最后commit锁在最前加、事务结束才释放磁盘刷数据是后台异步不阻塞事务提交四、查询VS更新 核心区别高频对比维度普通查询快照读更新语句当前读加锁不加锁走MVCC快照必加X行锁/间隙锁Undo日志不写入只读取先写undo旧数据Redo日志无完整WAL两阶段提交Binlog无记录逻辑变更并发读写不阻塞写写互斥会阻塞五、面试极简背诵版100字MySQL更新语句先经过Server层解析优化InnoDB加载数据页并加排他锁先写undo日志保存旧数据再修改内存脏页。基于WAL机制先落盘redo日志为prepare状态再写入binlog最后redo日志完成commit标记通过2PC保证日志一致。事务提交后释放锁后台异步刷盘持久化数据同时undo日志支撑事务回滚与MVCC快照读。