MySQL 基础教程
下面是一份 超完整、系统化、适合长期收藏的《MySQL 详细介绍(核心概念 + 架构原理 + 存储引擎 + 复制 + 日志 + 事务 + 索引 + 优化)》。内容非常全面,适合入门、进阶。
目录:
- MySQL 基础概念
- MySQL 架构组成
- InnoDB 存储引擎详解
- MySQL 数据文件布局
- 索引(Index)体系
- 锁(Locks)体系
- 事务(Transaction)与隔离级别
- 日志系统(Redo/Undo/Binlog)
- Buffer Pool(缓冲池)机制
- SQL 执行过程
- MySQL 复制(Replication)体系
- MySQL 高可用(HA)方案
- 常见性能优化方法
- 常见故障排查体系
- RDBMS:关系型数据库管理系统
- 支持 SQL
- 事务支持(ACID)
- 存储引擎可插拔
- MySQL 8.0 以后统一使用 InnoDB(默认)
关键特性:
- 安全可靠
- 高性能
- 开源
- 生态完善
负责所有与存储无关的功能:
- 连接管理
- 查询解析(Parser)
- 查询优化(Optimizer)
- 查询缓存(已废弃)
- 权限认证
- Binlog 写入
负责数据的实际存储与读取。
常见引擎:
- InnoDB(默认)
- MyISAM(已废弃)
- Memory
- CSV
- Archive
InnoDB 是核心,引擎特性:
- 事务(ACID)
- 行锁
- 自适应哈希索引
- 双写缓冲
- 崩溃恢复能力强
核心组件:
缓存:
- 数据页
- 索引页
- Undo
- Insert Buffer
默认大小较小,但建议设置为系统内存的 60%-80%。
保障持久性(D),崩溃恢复必需。
提供:
- 事务回滚
- MVCC(多版本控制)
防止数据页损坏(partial write)。
InnoDB 自动优化热点数据访问。
延迟写辅助结构,用于二级索引。
目录结构:
/var/lib/mysql/
├─ ibdata1 (系统表空间)
├─ ib_logfile0/ib_logfile1(redo 日志)
├─ *.ibd(每个表的数据 + 索引)
├─ binlog.000001(binlog)
├─ relay-log(从库)
└─ *.frm(8.0 之前)
MySQL 使用 B+Tree 索引(最重要)。
索引类型:
- 数据与主键同一棵 B+Tree
- 叶子节点存储整行数据
- 强烈建议业务表必须有主键
叶子节点存储主键值,因此存在 回表。
查询只用到索引,不用回表,性能最佳。
遵循最左前缀原则。
InnoDB 的锁非常丰富:
- 排它锁(X)
- 共享锁(S)
用于防止幻读(RR 隔离级别启用)。
行锁 + 间隙锁 组合。
- IS
- IX
用来与表锁兼容。
事务的 ACID:
- A 原子性(undo log)
- C 一致性
- I 隔离性(锁)
- D 持久性(redo log)
MySQL 支持 4 个隔离级别:
| 级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read Uncommitted | ✅ | ✅ | ✅ |
| Read Committed | ❌ | ✅ | ✅ |
| Repeatable Read(默认) | ❌ | ❌ | ⭐(避免部分幻读) |
| Serializable | ❌ | ❌ | ❌ |
InnoDB 默认 RR,使用:
- MVCC(非锁)
- 间隙锁(加锁)
同时防止不可重复读。
Redo Log
- WAL(Write Ahead Logging)
- 保证 crash-safe
- 确保数据最终刷入磁盘
Undo Log
- MVCC 快照
- 回滚事务
Binlog(Server 层)
- 用于复制
- 用于 PITR(时间点恢复)
MySQL 故障恢复顺序:
- 读取 redo log 恢复未刷盘数据
- rollback 未完成事务(undo log)
- binlog 做主从同步
Buffer Pool 是 MySQL 最重要的内存结构,用于缓存数据页与索引页,提高性能。
架构:
- Free List(空闲页)
- Flush List(脏页)
- LRU List(最近使用)
调优关键参数:
innodb_buffer_pool_size
innodb_buffer_pool_instances
innodb_buffer_pool_chunk_size
执行一条查询:
- 客户端连接器
- SQL Parser(解析器)
- Optimizer(优化器)
- Executor(执行器)
- 存储引擎读取数据
- 返回结果
执行一条写入:
- 写入 Buffer Pool
- 写 redo log(prepare)
- 写 binlog
- redo commit
- 刷盘
MySQL 提供三种复制:
| 模式 | 一致性 | 延迟 | 说明 |
|---|---|---|---|
| 异步 | 最差 | 可能很大 | 主库写成功即可返回 |
| 半同步 | 中等 | 较低 | 至少一个从库 ack |
| 增强半同步(MySQL 8) | 比半同步更强 | 更低 | 强制从库落盘后才 ack |
复制基于 binlog + relay log。
从一致性角度排序:
- 多数派提交
- 强一致性写入
最终一致性
优化方向:
- 使用合适索引
- 避免全表扫描
- 覆盖索引
- 尽量避免 JOIN 多超过 3 张表
- 合理选择数据类型
- CHAR vs VARCHAR
- 使用合适的主键(自增 / UUIDv7)
- 选择正确字段建立索引
- 避免索引失效(函数、类型不同等)
如:
innodb_buffer_pool_size
innodb_flush_log_at_trx_commit
max_connections
query_cache_size(8.0 已废弃)
- 内存足够大
- NVMe SSD
常用思路:
- 慢查询(slow query log)
- 表锁、行锁(SHOW ENGINE INNODB STATUS)
- 复制延迟(SHOW SLAVE STATUS)
- 连接数耗尽(Too many connections)
- 磁盘 IO 高
- Buffer Pool 不足
- 死锁(DEADLOCK)