MySQL Server 启动后到底加载了什么,创建表插入数据到底怎么存的存在哪

基于这篇后续:理解MySQL的原理

🧠 一、MySQL Server 启动后到底加载了什么

当你执行:

bash 复制代码
mysqld

或通过服务启动 MySQL 时,MySQL Server 会依次启动几个核心组件(类似 JVM 的启动阶段):

阶段 作用
1️⃣ 参数加载阶段 从配置文件(/etc/my.cnfmy.ini)读取参数,比如端口、数据目录、引擎类型、缓存大小等。
2️⃣ 存储引擎初始化 根据配置初始化 InnoDBMyISAM 等存储引擎。
3️⃣ 系统表加载 mysql 系统库加载用户、权限、时区、字符集等系统表。
4️⃣ 日志系统初始化 打开 redo log、binlog、undo log 文件。
5️⃣ 等待客户端连接 开启监听端口(默认 3306),等待客户端发起 TCP 连接。

🏗️ 二、创建数据库与表时,MySQL 实际做了什么?

当你执行以下语句:

sql 复制代码
CREATE DATABASE shop;
USE shop;
CREATE TABLE user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT
);

后台其实发生了这些事 👇

1. 创建数据库

MySQL 在数据目录(datadir)下创建一个文件夹:

复制代码
/var/lib/mysql/shop/

这就是你的 shop 数据库对应的物理目录

⚙️ 配置文件中的 datadir 参数定义了所有数据库文件的存储根目录。


2. 创建表时,MySQL 会生成以下文件(以 InnoDB 为例)

假设你用的是 InnoDB(默认引擎),那么在 shop/ 目录下会生成:

复制代码
shop/
 ├── user.frm       # 表结构定义(表头元数据)
 ├── user.ibd       # 表数据 + 索引存储文件(InnoDB 独立表空间)

📌 如果 innodb_file_per_table=OFF,那么数据不会存在 user.ibd,而是存在共享表空间 ibdata1 中。


💾 三、插入数据时,MySQL 做了哪些底层操作?

假设执行:

sql 复制代码
INSERT INTO user (name, age) VALUES ('Tom', 20);

后台流程如下(这是重点)👇👇👇


步骤 1:SQL 解析与执行计划生成(Server 层)

MySQL Server 负责 SQL 语法解析、优化、生成执行计划。

执行计划中确定:

  • 目标表的引擎;
  • 字段映射;
  • 索引使用策略。

然后把具体操作交给存储引擎执行(如 InnoDB)。


步骤 2:InnoDB 缓冲池写入(Buffer Pool)

InnoDB 不会立刻把数据写入磁盘,而是:

  • 先把记录写入内存中的 Buffer Pool
  • 在 Buffer Pool 中同时维护 数据页(Data Page)索引页(Index Page)

每个数据页大小为 16KB,一个表的数据会被拆成多个页。


步骤 3:记录 redo log(重做日志)

为了保证 事务持久性(D) ,InnoDB 同时写入一份日志到 redo log buffer 中,随后刷盘到磁盘的 redo 文件:

复制代码
/var/lib/mysql/ib_logfile0
/var/lib/mysql/ib_logfile1

redo log 记录的是「物理层面的修改」,比如:

"第 123 号数据页第 456 个字节写入了 0x01"

即使系统崩溃,也能用 redo log 恢复数据。


步骤 4:写入 binlog(二进制日志)

Server 层还会写一份 binlog(二进制日志),记录逻辑操作:

复制代码
INSERT INTO user (name, age) VALUES ('Tom', 20);

binlog 是用于 主从复制、数据恢复 的逻辑日志。


步骤 5:事务提交(两阶段提交)

为了保证 binlog 与 redo log 一致,InnoDB 采用了 两阶段提交

阶段 动作
阶段1 写入 redo log 并标记为 prepare 状态
阶段2 写入 binlog,成功后标记 redo log 为 commit 状态

✅ 这样即使中途崩溃,也能判断事务是否已完成。


步骤 6:后台刷盘(Flush)

InnoDB 有专门的后台线程负责把内存中被修改过的页(dirty page)写入到 user.ibd 文件中。

所以实际的数据是以「页」为单位写入的,而不是一行一行写。


📂 四、MySQL 是怎么找到这些数据的?

当你执行查询:

sql 复制代码
SELECT * FROM user WHERE id = 1;

流程如下:

  1. SQL 解析器 → 分析 SQL;

  2. 优化器 → 判断是否使用索引;

  3. 执行器 → 通过主键索引 B+Tree 找到对应页;

  4. InnoDB 引擎

    • 如果页在内存中(Buffer Pool),直接读取;
    • 否则从 user.ibd 文件加载对应页进内存;
  5. 返回结果。


🧩 五、存储格式总结(以 InnoDB 为例)

文件 内容 说明
.frm 表结构定义 Server 层定义字段信息
.ibd 数据页 + 索引页 InnoDB 独立表空间
ibdata1 系统表空间 存储共享元数据、Undo 信息
ib_logfile0/1 redo log 文件 持久化数据变更
mysql-bin.xxxxxx binlog 文件 主从同步、恢复用

⚠️ 六、总结一句话

MySQL 的数据最终都以「页(Page)」为单位写入 .ibd 文件中,

所有操作都会先经过 内存缓冲池(Buffer Pool) → redo log → 两阶段提交 → 后台刷盘 这一整套流程。

相关推荐
Java水解2 小时前
初识MYSQL —— 基本查询
后端·mysql
星光一影4 小时前
悬赏任务平台/拉新地推系统源码
redis·mysql·小程序·php·uniapp·html5
LvLuffy4 小时前
mac Android Studio配置adb环境(使用adb报错 adb: command not found)
macos·adb·android studio
卡卡酷卡BUG5 小时前
2025年Java面试题及详细解答(MySQL篇)
java·开发语言·mysql
盼哥PyAI实验室5 小时前
Python 正则表达式实战 + 详解:从匹配QQ邮箱到掌握核心语法
python·mysql·正则表达式
IT小哥哥呀6 小时前
MySQL慢查询优化实战:从日志分析到SQL重构全流程
mysql·性能分析·实战项目·数据库调优·sql性能·索引设计·慢查询优化
点心快奔跑6 小时前
超详细Windows系统MySQL 安装教程
数据库·windows·mysql
Neo Wordsworth7 小时前
phpstudy 无法启动mysql 但命令可以启动mysql
mysql·phpstudy
Cikiss7 小时前
图解 MySQL JOIN
数据库·后端·mysql