MySQL 经典问题
| Redis | 本质 |
|---|---|
| 缓存穿透 | 访问不存在的数据 |
| 缓存击穿 | 热点 Key 失效 |
| 缓存雪崩 | 大量 Key 同时失效 |
👉 本质都是:流量 / 并发直接打到 MySQL
如果 Redis 是“挡在 MySQL 前面的缓冲层” 那 MySQL 自身的问题,本质是: 并发、锁、IO、复制、一致性、容量
🔥 现象
- 瞬时 QPS 飙升
- CPU 100%
- 大量 Threads_running
- 慢查询暴增
☘️ 本质
- 大量请求 同时命中 MySQL
- 缓存失效 / 未使用缓存
- 大事务 + 热点行
🛠 解决方案
- Redis / 本地缓存
- 热点数据拆表 / 拆行
- 限流、熔断
- 读写分离
🔥 现象
- UPDATE / DELETE 卡死
- Lock wait timeout exceeded
- 死锁回滚
☘️ 本质
- 热点行
- 范围锁(Next-Key Lock)
- 索引失效 -> 锁表
🛠 解决方案
- 精确索引
- 减少事务时间
- 按固定顺序更新
- 使用 FOR UPDATE SKIP LOCKED
🔥 现象
- 单条 SQL 很慢
- QPS 不高但 MySQL 很卡
☘️ 本质
- 全表扫描
- 错误 Join
- 未命中索引
- 返回大量无效数据
🛠 解决方案
- EXPLAIN / ANALYZE
- 覆盖索引
- 拆 SQL
- 限制返回行数
🔥 现象
- 主库已更新,从库查不到
- 延迟几十秒甚至分钟
☘️ 本质
- Binlog 单线程回放
- 大事务
- 从库 IO/CPU 慢
🛠 解决方案
- ROW Binlog
- 并行复制
- 拆大事务
- 关键读走主库
🔥 现象
- IO Util 100%
- TPS 急剧下降
- 响应时间抖动
☘️ 本质
- 随机 IO
- Buffer Pool 不够
- Binlog / Redo / Data 混盘
🛠 解决方案
- 扩大 Buffer Pool
- Binlog/Redo 分盘
- SSD / NVMe
- 批量写入
🔥 现象
- 单表过亿
- ALTER TABLE 很慢
- 备份恢复时间爆炸
☘️ 本质
- 表设计不合理
- 没有提前拆分
- 单点数据库
🛠 解决方案
- 分库分表
- 冷热数据分离
- 在线 DDL
- 归档策略
| Redis 问题 | MySQL 对应问题 |
|---|---|
| 缓存穿透 | 慢查询 / 无效查询 |
| 缓存击穿 | 热点行锁竞争 |
| 缓存雪崩 | 并发风暴 / IO 打满 |
| Key 过期 | 大事务 / 大表 |
| 数据丢失 | 主从延迟 / 崩溃恢复 |
❌ 1. UPDATE 没走索引 -> 锁表
❌ 2. 大事务(循环内 UPDATE)
❌ 3. SELECT * + 大结果集
❌ 4. 事务里 RPC / sleep
❌ 5. 忽略主从延迟
👉 这些都等价于“绕过缓存直接压垮 MySQL”
| 风险 | 后果 |
|---|---|
| Binlog 未备份 | 无法 PITR |
| Buffer Pool 太小 | IO 打爆 |
| 单主无切换 | 长时间不可用 |
| 大表无归档 | 运维不可控 |
| 无慢日志 | 问题无法定位 |
Redis 的问题是“挡不住流量”, MySQL 的问题是“承不住并发、锁、IO 和容量”。