mysql结构的一些整理

举报
developer_Li 发表于 2026/08/07 18:52:43 2026/08/07
【摘要】 MySQL 整体逻辑架构图┌───────────────────────────────────────────────────────────────────────┐│ 1. 连接层 (Client Connectors) ││ [ JDBC / ODBC / Net / PHP / Pytho...

MySQL 整体逻辑架构图

┌───────────────────────────────────────────────────────────────────────┐
│                           1. 连接层 (Client Connectors)               │
│      [ JDBC / ODBC / Net / PHP / Python / Go / CLI / Navicat... ]     │
└───────────────────────────────────┬───────────────────────────────────┘
                                     (TCP/IP / 线程池连接)
                                    ▼
┌───────────────────────────────────────────────────────────────────────┐
│                           2. 服务层 (Server 层)                       │
│                                                                       │
│  ┌───────────────────────┐   ┌─────────────────────────────────────┐  │
│  │   连接管理器 & 权限验证  │   │          查询缓存 (Query Cache)     │  │
│    (Connection/Auth Manager)  (MySQL 8.0 已完全移除,老版本有)   │  │
│  └───────────┬───────────┘   └──────────────────┬──────────────────┘  │
│              │                                  │                     │
│              ▼                                  ▼                     │
│  ┌─────────────────────────────────────────────────────────────────┐  │
│  │   解析器 (Parser) & 预处理器 (Preprocessor)                        │  │
│  │   - 词法分析、语法分析、生成解析树 (AST)                        │  │
│  └───────────────────────────────┬─────────────────────────────────┘  │
│                                  │                                    │
│                                  ▼                                    │
│  ┌─────────────────────────────────────────────────────────────────┐  │
│  │   优化器 (Optimizer)                                            │  │
│  │   - 选择索引、决定表关联顺序、生成执行计划 (Execution Plan)       │  │
│  └───────────────────────────────┬─────────────────────────────────┘  │
│                                  │                                    │
│                                  ▼                                    │
│  ┌─────────────────────────────────────────────────────────────────┐  │
│  │   执行器 (Executor)                                             │  │
│  │   - 权限检查、调用存储引擎 API 读写数据                         │  │
│  └───────────────────────────────┬─────────────────────────────────┘  │
└───────────────────────────────────│───────────────────────────────────┘
                                     (通过统一的存储引擎 API 交互)
                                    ▼
┌───────────────────────────────────────────────────────────────────────┐
│                           3. 存储引擎层 (Pluggable Storage Engines)  │
│                                                                       │
│   ┌───────────────┐   ┌───────────────┐   ┌───────────────┐   ┌───┐   │
│   │    InnoDB     │   │    MyISAM     │   │    Memory     │   │...│   │
│   (事务、行锁、MVCC) (表锁、不支持) (内存表、极快) │   │   │   │
│   └───────┬───────┘   └───────┬───────┘   └───────┬───────┘   └───┘   │
└───────────│───────────────────│───────────────────│───────────────────┘
            ▼                   ▼                   ▼
┌───────────────────────────────────────────────────────────────────────┐
│                           4. 系统文件层 (File System / Disk)          │
│                                                                       │
│   [ 数据文件 (.ibd / .MYD) ]      [ 结构文件 (.frm / MyData) ]         │
│   [ 日志文件 (Redo / Undo / Binlog / Error Log / Slow Log) ]          │
└───────────────────────────────────────────────────────────────────────┘

数据页的流动逻辑

  【服务层/执行器】
         │
          (想要读取或修改某行数据)
┌────────────────────────────────────────┐
│ 【InnoDB 引擎层 - 内存 Buffer Pool】   │
│                                        │
│   ┌──────────┐  ┌──────────┐  ┌───┐    │
│   │ 数据页 A │  │ 数据页 B │  │... (内存中的数据页,完全映射磁盘结构)
│   └──────────┘  └──────────┘  └───┘    │
└────────────────────▲───────────────────┘
                      (若内存中没有,则产生 I/O 读入内存)
                     ▼
┌────────────────────────────────────────┐
│ 【系统文件层 - 磁盘 .ibd 文件】         │
│                                        │
│   ┌──────────┐  ┌──────────┐  ┌───┐    │
│   │ 数据页 A │  │ 数据页 B │  │... (磁盘上连续的 16KB 物理块)
│   └──────────┘  └──────────┘  └───┘    │
└────────────────────────────────────────┘

磁盘文件全景结构图

/var/lib/mysql/ (MySQL Data 根目录)
├── ibdata1                     <-- 系统表空间 (存储系统元数据、Change Buffer等)
├── undo_001                    <-- 回滚日志文件 (Undo Log)
├── undo_002
├── #innodb_redo/               <-- 重做日志文件夹 (Redo Log)
│   ├── @ib_redo0
│   └── @ib_redo1
├── ib_buffer_pool              <-- 缓冲池状态文件 (重启时快速恢复内存缓存)
│
├── oms/                        <-- 【数据库 oms 对应的文件夹】
│   ├── orders.ibd              <-- 【表 orders】(包含表结构 + 16KB 数据页 + 索引页)
│   └── users.ibd               <-- 【表 users】(包含表结构 + 16KB 数据页 + 索引页)
│
└── sys/                        <-- 系统自带的 sys 数据库文件夹
    └── ... 

索引

聚簇索引(Clustered Index)的存储:它就是表本身

在 InnoDB 中,一张表的数据行在磁盘上不是杂乱无章排放的,而是必须按照主键的顺序,组织成一棵 B+ 树。叶子节点(Leaf Nodes): 存放的是真正的、完整的整行数据(包含你定义的 order_no, price, create_time 等所有字段)。非叶子节点(Non-Leaf Nodes): 只存放“主键 ID + 下一层数据页的指针”。文件层表现: 我们之前提到的那些 16KB 的数据页,有些变成了这棵树的枝干(非叶子节点页),有些变成了这棵树的树叶(叶子节点页)。它们都统统存在 表名.ibd 文件里。

二级索引(Secondary Index)的存储:它是另一棵 B+ 树

如果你给表里的 order_no(订单号)字段加了一个普通索引,MySQL 会怎么存?独立成树: MySQL 会在同一个 表名.ibd 文件里,额外再划出一批 16KB 的数据页,为 order_no 单独构建一棵全新的 B+ 树。叶子节点: 这棵二级索引树的叶子节点里,不包含整行数据的全部字段。它只存放两样东西:当前索引列的值 (order_no) + 对应的主键 ID。文件层表现: 这棵新树的数据页和主键树的数据页混交在同一个 .ibd 文件里,通过页头(Page Header)里的标记来区分自己属于哪一个索引。

索引在 .ibd 文件内部的物理全景图

【表名.ibd 文件 (总大小: N 个 16KB 页面)】
┌────────────────────────────────────────────────────────────────────────┐
│  [文件头/表结构元数据 SDI]  (MySQL 8.0 特有,占前几个页)                │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  【主键 B+区域 (聚簇索引)】                                          │
│   ├── [ 16KB 索引页 ] ───> [ 16KB 索引页 ]  (非叶子节点:只存 ID + 指针) │
│   └── [ 16KB 数据页 ] ───> [ 16KB 数据页 ]  (叶子节点:存【完整整行数据】) │
│                                                                        │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  【order_no 索引 B+区域 (二级索引)】                                 │
│   ├── [ 16KB 索引页 ] ───> [ 16KB 索引页 ]  (非叶子节点:只存单列+指针)  │
│   └── [ 16KB 数据页 ] ───> [ 16KB 数据页 ]  (叶子节点:只存【order_no+主键ID)
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

索引是如何在文件层协同工作的?(回表查询)

当你执行:SELECT * FROM orders WHERE order_no = ‘ABC’;执行器调用接口,InnoDB 打开 orders.ibd 文件。引擎先去 order_no 二级索引树 的物理页面里疯狂二分查找,在叶子节点找到了 ‘ABC’,并拿到了它绑定的小尾巴——主键 id = 99。因为你要的是 SELECT *(所有字段),二级索引树里没有其他字段,这就触发了 “回表”。引擎拿着 id = 99,转头去同一个文件内的 主键 B+ 树 的物理页面里再次查找,在叶子节点顺利捞出 id=99 的完整整行数据,返回给用户。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。