6、MySQL 总结

一、体系结构

1. 一条 SQL 的旅程

  • 连接器:认证、权限、连接数
  • 解析器:词法语法,生成语法树
  • 优化器:选索引,定 JOIN 顺序
  • 执行器:调引擎接口,逐行过滤
  • InnoDB:Buffer Pool 到 16KB 页

2. 内存结构

  • Buffer Pool:给物理内存 50 到 70%
  • Change Buffer:只服务非唯一二级索引
  • Log Buffer:默认 16M
  • LRU 冷热分区:防全表扫描污染

3. 磁盘结构

  • 表空间、段、区 1MB、页 16KB、行
  • 行溢出阈值约 8KB,超出走溢出页

4. 引擎对比

  • InnoDB:事务、行锁、MVCC
  • MyISAM:表锁
  • Memory:易失

二、索引

1. 为什么是 B+ 树

  • 哈希:不支持范围与排序
  • 红黑树:树高约 24 层
  • B 树:非叶子存数据,树更高
  • B+ 树:矮胖、叶子有序、IO 稳定
  • 三层约 2000 万行,最多 3 次 IO

2. 聚簇与二级索引

  • 聚簇索引:叶子存整行,一表一个
  • 二级索引:叶子存索引列加主键
  • 回表:两次 B+ 树查找
  • 覆盖索引:Extra 显示 Using index

3. 最左前缀

  • 范围查询后,后续列只能 ICP 过滤
  • 跳过最左列,完全用不上

4. 索引失效

  • 列上函数或运算
  • 左模糊 like %x
  • 隐式类型转换:varchar 不加引号
  • OR 一侧无索引
  • 取反、不等于、NOT IN,区分度太低

5. 设计方法

  • 选择性 10% 以上才有意义
  • 等值在前、范围在后、排序跟上
  • 索引不超过 5 到 6 个,前缀索引不能覆盖

6. 自增主键优势

  • 顺序写,不页分裂
  • 二级索引更小,整型比较更快

三、事务、MVCC 与锁

1. ACID 实现

  • 原子性:undo log
  • 隔离性:MVCC 加锁
  • 持久性:redo log 加 double write

2. 隔离级别

  • 默认 RR
  • RC:每条语句新建 ReadView
  • RR:事务内复用 ReadView
  • RR 幻读:快照读 MVCC,当前读临键锁

3. MVCC

  • 隐藏字段 TRX_ID 与 ROLL_PTR
  • undo 版本链,顺链找旧版本
  • ReadView 四字段:m_ids 与 min、max

4. 锁

  • 行锁锁索引项,不是行本身
  • 记录锁、间隙锁、临键锁,唯一等值只加记录锁
  • MDL 导致 DDL 排队雪崩
  • 无索引,退化为锁全表

5. 死锁

  • 交叉加锁成环
  • 回滚代价小的事务
  • 排查 INNODB STATUS 与 data_lock_waits
  • 预防:统一顺序、短事务、唯一索引

6. 长事务危害

  • undo 不释放,History list 膨胀
  • 锁持有久,拖慢主从
  • MDL 阻塞 DDL

四、日志系统

1. redo log

  • 物理日志,循环写
  • WAL:随机写变顺序写,且 crash-safe
  • 8.0.30 起 redo_log_capacity 统一控制
  • 容量太小,checkpoint 频繁,周期卡顿

2. undo log

  • 事务回滚
  • MVCC 版本链

3. binlog

  • Server 层,逻辑日志,追加写
  • ROW 格式,主从绝对一致
  • 用于复制与 PITR

4. 两阶段提交

  • redo prepare,写 binlog,再 commit
  • binlog 完整则提交,否则回滚

5. double write

  • 防页写一半导致的页损坏
  • 代价约一倍写放大

6. 双 1 配置

  • flush_log_at_trx_commit 设为 1
  • sync_binlog 设为 1
  • 日志类可降为 2 加 100 换吞吐

五、优化一:系统层

1. CPU

  • 8 到 16 核覆盖多数 OLTP,超 32 核收益递减
  • 主频决定单条复杂 SQL

2. 内存

  • Buffer Pool 占 50 到 70%
  • swap 必须为 0,换页即雪崩

3. 磁盘

  • NVMe 优于 SATA SSD,SATA SSD 优于 HDD
  • RAID10,不用 RAID5,写惩罚重
  • XFS 加 noatime,调度器 none,关 THP

4. 检查手段

  • iostat 与 iotop 看 util、await 与进程
  • fio 测 IOPS 与延迟
  • 优先级:SSD 大于内存,内存大于 CPU

六、优化二:配置层

1. 内存参数

  • buffer_pool_size 最重要的一项
  • 实例数 8,每个至少 1G
  • tmp_table_size 与 heap 必须相等

2. 连接参数

  • max_connections 按连接池总数算
  • max_used_connections 超 80% 才扩容
  • wait_timeout 收 300 到 600

3. 刷盘参数

  • redo 4 到 8G,太小会周期卡顿
  • flush_method 用 O_DIRECT
  • io_capacity 2000 到 4000,flush_neighbors 设 0

4. 参数模板

  • 4C8G:BP 5G,连接 500,redo 2G
  • 16C64G:BP 40G,连接 1000,redo 8G

5. 调参纪律

  • 一次只改一个参数
  • 先预发后生产,留版本记录

七、优化三:SQL 与索引

1. 定位四步

  • 慢日志与 ps digest 找慢 SQL
  • EXPLAIN 看执行计划
  • 判断瓶颈:行数、回表、排序

2. EXPLAIN 关键字段

  • type 从 const 到 ALL,越左越好
  • key 为 NULL 说明优化器放弃索引
  • rows 与 filtered 估扫描量
  • Extra 看 Using index 与 filesort
  • EXPLAIN ANALYZE 看实际耗时

3. 典型改写

  • 深分页:延迟关联或游标法
  • 大事务拆批,批量插入 500 到 1000 行一批
  • 避免 SELECT *,破坏覆盖索引
  • JOIN 被驱动表必须有索引
  • ORDER BY 与 GROUP BY 走索引
  • 大表 DDL 用 INSTANT 或 gh-ost
  • COUNT 走最小二级索引或计数表

八、优化四:架构与运维

1. 主从复制

  • 主库 binlog 到 dump 到 relay 到回放
  • GTID 主从切换必备
  • 半同步 AFTER_SYNC 不丢数据
  • 并行复制 LOGICAL_CLOCK

2. 主从延迟

  • 从库规格低于主库
  • 大事务、无主键表、从库读压力
  • 用 pt-heartbeat 替代旧指标

3. 读写分离

  • 写主读从
  • 写后短时强行走主库
  • ProxySQL 或 ShardingSphere

4. 高可用

  • MHA 已停更
  • MGR 基于 Paxos,官方推荐
  • 三个坑:脑裂、丢数据、应用不知切换

5. 备份恢复

  • XtraBackup 物理热备首选
  • mysqldump single-transaction 逻辑备
  • binlog 做 PITR,按时间点恢复
  • 延迟从库防误删,每月演练

6. 监控告警

  • 连接数超 80%,BP 命中率低于 99%
  • 慢查询增速、锁等待、History list
  • 主从延迟超 10 秒,磁盘超 80%

九、面试速答

1. 回答公式

一句结论、两点机制、一句取舍。

2. 最高频八问

  1. 一条 SQL 的执行流程
  2. 为什么用 B+ 树
  3. 回表与覆盖索引
  4. MVCC 与 ReadView
  5. RR 能否防幻读
  6. 两阶段提交为什么需要
  7. 慢 SQL 怎么排查
  8. 深分页与主从延迟怎么治

十、数字与信号

  • 16KB 页,三层 B+ 树约 2000 万行
  • 50 到 70% 给 Buffer Pool
  • 双 1 保证不丢数据
  • 99% 命中率警戒线
  • type 为 ALL 且 rows 大,等于没走索引
相关推荐
凤凰院凶涛QAQ1 小时前
《MySQL内核拆解:从SQL到InnoDB》(三) : 数据库设计 & 聚合查询 & 分组查询
数据库·sql·mysql
Decay__2 小时前
01_MySQL 体系架构全解 —— 连接层、SQL 层、存储引擎层与 InnoDB 深入
运维·数据库·sql·mysql·架构
Linux_cy2 小时前
nginx 502 排查手册:九种原因分类、定位命令与检查顺序
linux·运维·服务器·网络·数据库·nginx·ssh
在多学一点2 小时前
MySQL_DDL的基本命令
数据库·mysql·adb
是程序喵呀3 小时前
Redis实现持久化
数据库·redis·缓存
z06.4 小时前
MySQL存储引擎
数据库·mysql
小徐不徐说4 小时前
数据库存储基础:理解表结构、主键、事务与 BLOB
开发语言·数据库·c++·qt·程序设计
JackLam4 小时前
Gitea HTTPS 反向代理配置
数据库
量子物理学4 小时前
oracle plsql instantclient 安装
数据库·oracle