当前位置: 首页 > news >正文

MySQL 全体系深度解析(存储引擎、事务、日志、MVCC、锁、索引、执行计划、复制、调优)

MySQL 的设计本质是一整套围绕“索引 + 日志 + 事务 + 并发控制 + I/O 优化”构建的系统。

全篇结构如下:

  1. MySQL 存储引擎:InnoDB vs MyISAM
  2. InnoDB 索引体系:B+ 树、二级索引、覆盖索引、回表
  3. MySQL 并发控制:MVCC 原理
  4. MySQL 锁机制(行锁、间隙锁、Next-Key)
  5. 日志体系:redo log / undo log / binlog
  6. 事务隔离级别与两阶段提交
  7. 崩溃恢复机制(Crash Recovery)
  8. 索引下推 ICP
  9. EXPLAIN 执行计划详解
  10. 主从复制原理
  11. MySQL 调优体系(索引、SQL、缓存、架构)

读完这篇,你就掌握了 MySQL 从存储到查询、从并发到恢复、从索引到复制的整体视角。


一、存储引擎:InnoDB 与 MyISAM 的本质区别

InnoDB 是 MySQL 默认也是最核心的引擎。
MyISAM 曾经流行,但现在几乎只用在非常特殊的场景。

核心区别如下:

1. 事务支持

  • InnoDB:支持 ACID,具备提交、回滚、崩溃恢复能力
  • MyISAM:不支持事务

2. 锁粒度

  • InnoDB:行级锁(Record)、间隙锁、Next-Key
  • MyISAM:表级锁

InnoDB 对高并发写入场景友好得多。

3. 崩溃恢复

  • InnoDB:有 redo log、undo log
  • MyISAM:数据容易损坏,需要手动修复

4. 外键支持

  • InnoDB:支持
  • MyISAM:不支持

5. 索引组织方式

  • InnoDB:聚簇索引(主键即数据)
  • MyISAM:数据和索引分离(非聚簇)

一句话总结:
InnoDB 是现代 OLTP(高并发事务系统)的标配;
MyISAM 几乎退出历史舞台。


二、InnoDB 的索引体系:B+Tree、二级索引、覆盖索引、回表

索引是 MySQL 性能的基石。

1. 为什么 MySQL 选择 B+ 树作为索引结构?

B+ 树的优势包括:

  1. 磁盘友好:节点大,一次 I/O 可以读入大量 key
  2. 树高度低:百万级数据树高只有 3~4 层
  3. 范围查询高效:叶子节点链表结构天然支持范围扫描
  4. 所有值存储在叶子节点,路径一致、高效

它是“磁盘 + 关系型查询”的最佳选择。

2. 聚簇索引(主键索引)

InnoDB 的主键索引是聚簇索引:

  • 主键节点的叶子节点即为整行数据
  • 这意味着访问主键是最快的路径
  • 如果没有定义主键,InnoDB 会自动生成 row_id

3. 二级索引(普通索引)

二级索引的叶子节点存储的是“主键”。

因此查询流程为:

二级索引定位主键 → 回到主键索引树 → 取出数据

这就叫 回表

4. 覆盖索引(避免回表)

如果查询只需要的字段都在索引里,就不需要回表。

例如:

SELECT age FROM user WHERE age > 20;

如果 age 单列索引存在,则直接在索引文件中返回结果。

覆盖索引能显著提升性能,因为避免访问聚簇索引。


三、MVCC:InnoDB 如何实现非阻塞读?

MVCC(多版本并发控制)允许:

  • 读不阻塞写
  • 写不阻塞读
  • 普通 SELECT 不加锁

MVCC 依赖三个关键结构:

1. undo log(回滚日志)

记录数据旧版本,用于构建“版本链”。

2. Read View(读视图)

决定当前事务能看到哪些版本。

已提交读隔离级别下的事务在每次查询的开始都会生成一个独立的ReadView,而可重复读隔离级别则在第一次读的时候生成一个ReadView,之后的读都复用之前的ReadView

3. 隐藏字段

每条记录有两个隐藏字段:

  • trx_id(当前版本属于哪个事务)
  • roll_pointer(指向 undo log)

数据结构大致如下:

最新版本 → 上一版本 → 再上一版本

快照读过程:

  • 找到第一个符合 Read View 可见性规则的版本
  • 返回给事务,不加锁

这就是 InnoDB 能做到高并发的核心原因。


四、锁机制:记录锁、间隙锁、Next-Key Lock

InnoDB 的锁体系为了解决并发更新与幻读问题。

1. 行锁(Record Lock)

锁住某一行的索引记录。

2. 间隙锁(Gap Lock)

锁住一个索引范围内的空隙,例如:

(10, 20)

防止插入,解决幻读。

3. Next-Key Lock

记录锁 + 间隙锁
用于可重复读隔离级别下的当前读(select … for update)。

Next-Key 是 InnoDB 避免幻读的武器。


五、redo log、undo log、binlog 的关系(核心)

MySQL 的日志体系非常精妙,是高可靠性的基础。

1. redo log:物理日志(InnoDB)

  • 属于 InnoDB 引擎层
  • 保证崩溃恢复(crash-safe)
  • 采用 WAL:先写日志再写磁盘

2. undo log:逻辑日志(InnoDB)

  • 用于回滚(rollback)
  • 用于 MVCC 的旧版本链

3. binlog:逻辑日志(Server 层)

  • 用于主从复制
  • 用于归档恢复(PITR)

4. 两阶段提交(2PC)

为了保证 redo 与 binlog 一致性,MySQL 使用两阶段提交:

1. undo log + redo prepare
2. 写入 binlog
3. redo commit

保证主从复制与本地事务一致。


六、崩溃恢复(Crash Recovery)是怎么实现的?

InnoDB 的崩溃恢复流程:

  1. 读取 redo log 的 checkpoint
  2. 从 checkpoint 开始重放 redo log
  3. 未提交事务,用 undo log 做回滚
  4. double write buffer 防止部分写入导致页损坏

这就是为什么 InnoDB 具有 crash-safe 能力。


七、索引下推(ICP)

索引下推是在存储引擎层提前过滤数据,减少回表次数。

例如:

WHERE age > 20 AND name = 'Jack'

ICP 会在索引层先判断条件,极大减小访问聚簇索引的次数。


八、Explain 执行计划详解

Explain 是 SQL 调优的核心工具。

最重要的字段:

id:执行顺序

越大越先执行。

type:访问类型

从好到差:

system > const > eq_ref > ref > range > index > ALL

ALL 表示全表扫描,需要优化。

key:使用的索引

key_len:索引使用长度

rows:扫描行数

Extra:额外信息

Extra 中非常重要的标记:

  • Using index(覆盖索引)
  • Using where
  • Using index condition(索引下推)
  • Using temporary
  • Using filesort

使用 temporary 或 filesort 通常是性能瓶颈。


九、MySQL 主从复制

主从复制基于 binlog:

  1. 主库写 binlog
  2. 从库 IO 线程拉取 binlog
  3. 从库 SQL 线程执行 binlog 重放

复制模式:

  • 异步复制
  • 半同步复制
  • 全同步复制

核心问题:主从延迟(尤其是大事务)。


十、MySQL 调优体系:索引、SQL、缓存、架构

调优是 MySQL 的最终目标。

1. 索引调优

  • 避免 select *
  • 使用覆盖索引
  • 利用最左前缀原则
  • 避免函数、运算破坏索引使用
  • 避免前缀模糊匹配(like ‘%xx’)

2. SQL 调优

  • 避免子查询(使用 join 或 exists)
  • 适当分批查询(limit + where)
  • 合理使用 join 顺序
  • 使用 explain 分析优化路径

3. 缓存调优

  • Redis 承担热点缓存
  • 避免数据库频繁磁盘 IO
  • 使用缓存一致性策略

4. 架构调优

  • 主从复制、读写分离
  • 分库分表
  • 中间件(ProxySQL / MyCat)
  • 双写一致性设计
  • 高可用架构(MGR、MHA)

最终总结

MySQL 的底层逻辑可概括为四句话:

  1. InnoDB 通过 B+Tree 索引和聚簇索引实现高性能数据访问
  2. 通过 MVCC、行锁和 Next-Key Lock 实现高并发一致性控制
  3. 通过 redo / undo / binlog 和两阶段提交实现事务持久化和复制一致性
  4. 通过 explain 分析、索引优化、SQL 优化和架构设计实现整体性能提升
http://www.dtcms.com/a/605102.html

相关文章:

  • SpringMVC基础教程(1)--MVC/DispathcerServlet
  • 在streampark运行paimon-flink-action-1.20.0.jar
  • AI得贤面试智能体:重构企业招聘新范式
  • 硅基计划6.0 陆 JavaEE HttpHttps协议
  • 稳定边界层高度参数化方案的回归建模
  • 企业网站推广方法wap网站预览
  • 可以做推广的门户网站wordpress适合中国的小插件介绍
  • Dubbo服务治理全解析:从零搭建高可用微服务架构
  • java List怎么转换为Vector
  • 2023年辽宁省数学建模竞赛-B题 数据驱动的水下导航适配区分类预测-基于支持向量机对水下导航适配区分类的研究
  • 机器学习--KNN算法中的距离、范数、正则化
  • openGauss向量数据库功能实操测评:轻量部署下的高维检索能力
  • php做网站还是linuxseo服务外包费用
  • 《算法通关指南:算法基础篇 ---- 二维前缀和 — 1. 【模板】二维度前缀和,2.激光炸弹》
  • SpringBoot+openGauss DataVec构建高效RAG知识库实践
  • JVM 垃圾回收算法的详细介绍
  • 生成式引擎优化(GEO)实用指南(三):结构化内容与AI优化策略
  • 114啦怎么建设网站怎么样推广自己的公司
  • 可视化图标开发“懂一点”|数据可视化术语表
  • SpringMVC(1)学习
  • 高频Linux 面试题
  • 芜湖效能建设网站重庆发布公众号
  • Spring Boot 多环境配置详解:Maven Profile vs 启动参数注入
  • 《Chart.js 饼图:高效与灵活的数据可视化工具详解》
  • 力扣每日刷题251113
  • erp网站开发网站后台管理系统源码下载
  • Spring IOC核心原理与实战技巧
  • 计算中央子午线(Excel版)
  • HarmonyOS Menu组件深度自定义:突破系统默认样式的创新实践
  • 【Rust】从0到1开发和运行Web相关功能,并简单实现数据库连接和查询