【MySQL底层】从查询到更新、redo/binlog、两阶段提交超详细通俗易懂
目录
- 一、MySQL整体架构
- 二、一条查询SQL完整执行流程(超细粒度)
- 三、一条更新SQL完整执行流程(面试必考)
- 四、两大日志深度解析(彻底解决重复疑惑)
- 五、两阶段提交(2PC)通俗易懂讲解
- 六、缓冲池(Buffer Pool)终极通透理解
- 七、主从复制原理(通俗版)
- 八、全文核心总结(背诵清单)
- 九、初学者高频疑惑复盘
- ✨ 写在最后
很多初学者学习MySQL时,都会被:执行流程、缓冲池、redo log、binlog、两阶段提交、优化器这些底层概念搞懵。
本文从零梳理MySQL全套底层执行原理,无晦涩废话、无跳跃逻辑、通俗易懂。
适合人群:零基础、初学、面试背诵、想要搭建MySQL知识架构
内容全部通俗易懂,看完彻底搞懂MySQL底层运行机制
一、MySQL整体架构
MySQL 整体分为两大层,一定要区分清楚,这是所有底层知识的地基。
1.1 架构分层
-
Server服务层:连接器、查询缓存、分析器、优化器、执行器、binlog
-
InnoDB存储引擎层:缓冲池、数据页、磁盘文件、redo log、事务、锁
1.2 分层核心区别
-
Server层:不碰真实数据,只负责解析SQL、优化SQL、下发执行指令
-
引擎层:真正读写数据,操作内存、磁盘、日志
一句话总结:上层管逻辑,下层管数据。
二、一条查询SQL完整执行流程(超细粒度)
示例SQL:
SELECT name,age FROM user WHERE id=1;
整条SQL从上到下执行顺序:连接器 → 查询缓存 → 分析器 → 优化器 → 执行器 → 存储引擎
2.1 连接器(Connector)
-
客户端通过TCP协议连接MySQL(3306端口)
-
校验账号、密码、连接权限
-
为本次连接分配独立线程,维持会话状态
2.2 查询缓存(Query Cache,8.0 彻底删除)
-
原理:key为SQL文本,value为查询结果
-
只要表发生增删改,整张表缓存全部失效
-
淘汰原因:命中率极低、锁竞争严重、维护成本高
2.3 分析器(语法校验)
作用:检查SQL是否合法,不合法直接报错。分为三步:
-
词法分析:拆分SQL关键字,识别SELECT、FROM、WHERE、字段、表名
-
语法分析:判断SQL书写语法是否合规
-
元数据校验:校验表、字段是否存在,用户是否拥有查询权限
日常报错:表不存在、字段不存在、语法错误,全部卡在分析器阶段。
2.4 优化器(最核心、最难理解)
你写的SQL只表达想要什么数据,优化器决定怎么拿最快。
优化器内部工作流程:
-
SQL重写:简化SQL、合并条件、剔除无效判断
-
读取统计信息:获取表行数、索引离散度、数据分布情况
-
成本计算:计算多种执行方案的总成本
-
IO成本:磁盘读取数据页次数(开销最大)
-
CPU成本:内存过滤、数据计算开销
最终产出:执行计划
包含:选用哪个索引、是否全表扫描、是否回表、表连接顺序。
重点:索引不是加了就一定走。优化器判定全表扫描成本更低,就会主动放弃索引。
2.5 执行器
-
读取优化器生成的执行计划
-
向存储引擎下发数据读取指令
-
重要分界点:执行器之后,正式进入InnoDB存储引擎层
2.6 InnoDB存储引擎(执行器之后流程)
这是初学者最容易疑惑的底层区域,全程细粒度拆解:
① 访问缓冲池(Buffer Pool)
-
优先在内存中查找目标数据页
-
内存命中:直接读取,速度极快
-
内存未命中:触发磁盘IO
② 磁盘IO加载数据
-
InnoDB最小读写单位:16KB数据页(不是单行数据)
-
将磁盘数据页加载到缓冲池内存中
③ 索引定位数据
-
通过B+树索引快速检索数据
-
主键索引直接拿到完整数据,普通索引需要回表查询
④ 过滤数据并返回
-
执行where条件过滤、截取查询字段
-
数据原路返回:引擎→执行器→客户端
2.7 查询流程总结
连接→解析→优化→执行→引擎查缓冲池→无命中读磁盘→索引查找→返回数据。查询语句不产生任何日志。
三、一条更新SQL完整执行流程(面试必考)
示例SQL:
UPDATE user SET age=20 WHERE id=1;
3.1 上层流程和查询完全一致
连接器 → 分析器 → 优化器 → 执行器
3.2 执行器之后(引擎层核心流程)
-
查找缓冲池:定位目标数据页,无命中则从磁盘加载
-
修改内存数据:仅修改内存,磁盘数据不变,生成脏页
-
redo log prepare:写入物理日志,标记为待提交状态
-
写入binlog:服务层写入逻辑日志,强制落盘
-
redo log commit:修改日志状态,事务正式完成
-
后台异步刷盘:后台线程缓慢将脏页写入磁盘,不阻塞用户操作
3.3 更新流程万能口诀
改内存 → redo预备 → binlog落盘 → redo提交 → 后台异步刷磁盘
四、两大日志深度解析(彻底解决重复疑惑)
很多初学者疑问:redo log和binlog都记录修改,是不是重复?
答案:完全不重复,各司其职,缺一不可。
4.1 redo log(引擎层日志)
-
别名:崩溃救命日志
-
归属:InnoDB存储引擎层
-
日志类型:物理日志(记录:第几号数据页、哪个偏移量、改成什么值)
-
核心作用:MySQL断电崩溃,重启自动恢复数据
-
写入方式:循环写入、固定大小、会覆盖旧数据
-
写入位置:执行器之后,引擎内部
4.2 binlog(服务层日志)
-
别名:归档总账本
-
归属:MySQL Server服务层
-
日志类型:逻辑日志(记录:SQL语句、行数据变更记录)
-
核心作用:数据备份、时间点恢复、主从复制
-
写入方式:追加写入、永久递增、不会覆盖
4.3 为什么需要两个日志?
-
redo log:引擎自保,保证崩溃不丢数据
-
binlog:对外服务,负责备份、复制、数据追溯
历史由来:binlog是MySQL原生日志;InnoDB为了支持事务和崩溃恢复,后期新增redo log。
五、两阶段提交(2PC)通俗易懂讲解
5.1 存在意义
保证 redo log 与 binlog 事务状态完全一致,防止主从数据错乱、数据丢失。
5.2 两阶段执行流程
-
第一阶段(Prepare准备):redo log写入磁盘,标记为待提交
-
第二阶段(Commit提交):binlog成功落盘,修改redo log为提交状态
5.3 三种断电场景(必背面试题)
-
Prepare之前断电:两条日志均不完整,事务回滚
-
Prepare完成、binlog未写完断电:无完整binlog,判定事务无效,回滚
-
binlog写完、redo未commit断电:binlog完整,判定事务合法,MySQL自动补提交
5.4 总结
日志一致性全部由MySQL自动处理,开发人员无需手动干预。
六、缓冲池(Buffer Pool)终极通透理解
6.1 数据真实存储位置
-
永久数据:全部存储在磁盘
-
内存:仅做临时缓存,断电数据丢失
6.2 为什么优先读内存?
内存读写速度是磁盘的1000倍,优先读内存是为了减少磁盘IO、提升数据库性能。
6.3 缓冲池固定位置(重点纠正误区)
-
缓冲池属于 InnoDB引擎层
-
无论查询、更新,必须在执行器执行之后才访问缓冲池
-
前期简化教学把缓冲池前置讲解,属于通俗演示,标准架构固定在执行器后方
6.4 脏页概念
内存数据已修改、磁盘数据未修改的数据页,称为脏页。由后台线程异步刷入磁盘。
七、主从复制原理(通俗版)
7.1 什么是主从复制?
-
主库(Master):专门处理写操作
-
从库(Slave):同步主库数据,处理读操作
7.2 同步核心依赖
只依赖 binlog。从库持续拉取主库binlog,重复执行SQL,实现数据同步。
7.3 主从复制作用
-
实现读写分离,分担数据库压力
-
实时备份数据,防止主库宕机数据丢失
-
做数据灾备、异地部署
八、全文核心总结(背诵清单)
-
两大分层:Server层处理逻辑,引擎层处理数据
-
查询流程:上层走完执行器,引擎优先读内存,无内存再读磁盘,无日志生成
-
更新流程:改内存→redo预备→binlog落盘→redo提交→后台刷盘
-
双日志区别:redo物理崩溃恢复、binlog逻辑备份复制
-
缓冲池:唯一属于引擎层,永远在执行器之后访问
-
两阶段提交:保证双日志一致性,断电自动判断回滚/提交
-
主从复制:仅依靠binlog实现数据同步
九、初学者高频疑惑复盘
疑惑问题
标准答案
数据存在磁盘还是内存?
永久存磁盘,内存仅缓存
为什么优先读取内存?
减少磁盘IO,内存速度快千倍
两大日志是否重复?
绝不重复,分工明确
redo log写入时机?
执行器之后,引擎内部写入
缓冲池为什么看似出现两次?
同一个缓冲池,前期为教学简化排版
优化器作用?
计算成本,选出最优执行方案
断电数据会丢失吗?
不会,两阶段提交自动恢复
主从复制依靠什么?
仅依靠binlog
✨ 写在最后
本文无任何摘抄、纯通俗易懂底层梳理,专门为初学者搭建完整MySQL底层知识架构。
建议收藏反复阅读,吃透本文,你将彻底弄懂MySQL查询、更新、日志、缓冲池、两阶段提交全部底层逻辑,轻松应对面试和工作开发。
更多推荐




所有评论(0)