MySQL 故障排查与优化
一、日常故障排查思路
-
先看服务状态
- 启动失败:查看错误日志
error.log,常见原因端口占用、配置错误、权限不足、磁盘满。 - 无法连接:检查端口 3306、防火墙、bind-address、授权用户主机限制。
- 启动失败:查看错误日志
-
查看关键日志
- 错误日志:记录启动、崩溃、严重异常。
- 慢查询日志:定位低效 SQL。
- 二进制日志:数据恢复、主从同步问题排查。
-
连接与权限类故障
Access denied:密码错误、主机未授权、用户不存在。Too many connections:连接数超限,调大max_connections或优化连接复用。
-
锁等待与阻塞
- 查看锁等待:
show processlist;、show engine innodb status; - 长事务未提交导致锁阻塞,需 kill 异常会话。
- 查看锁等待:
-
主从复制故障
- 同步延迟:网络、大事务、从库性能不足。
- 同步中断:主键冲突、语句执行错误、binlog 丢失。
- 修复:跳过错误、重新同步、校验数据一致性。
二、性能优化方向
1. 配置优化(my.cnf/my.ini)
- 连接与并发
max_connections:根据业务调整,避免过高。wait_timeout/interactive_timeout:减少空闲连接占用。
- InnoDB 核心
innodb_buffer_pool_size:建议物理内存 50%~70%。innodb_log_file_size:提高写入性能,不宜过大。innodb_flush_log_at_trx_commit:1 强安全,2 性能高,0 最高性能。
- 查询缓存
- MySQL 8.0 已移除,5.7 建议关闭避免失效开销。
2. SQL 优化
- 避免
select *,只查需要字段。 - 避免
where 1=1等无意义条件,避免隐式类型转换。 - 少用
order by rand()、in大量值、深度子查询。 - 大
limit offset分页优化:改为主键范围查询。 - 使用
explain分析执行计划,重点看type、key、rows、Extra。
3. 索引优化
- 高频查询字段建索引,避免冗余索引。
- 联合索引遵循最左前缀原则。
- 避免在索引列上使用函数、运算,导致索引失效。
- 定期使用
pt-index-usage清理无用索引。
4. 表结构优化
- 使用合适字段类型:int 替代 bigint、datetime 替代 varchar。
- 大字段拆分到附属表,避免行过大。
- 避免频繁
alter table,低峰期执行。 - 分区表优化超大表查询与清理。
5. 架构与运维优化
- 读写分离:主库写、从库读。
- 分库分表:解决单表过大问题。
- 定期优化表:
optimize table、清理历史数据。 - 监控:CPU、内存、IO、连接数、慢查询、锁等待、主从延迟。
三、常用排查命令
sql
-- 查看连接与运行状态
show processlist;
show full processlist;
-- 查看 InnoDB 状态(锁、事务、阻塞)
show engine innodb status;
-- 查看变量与状态
show variables like '%conn%';
show status like 'Threads_connected';
show status like 'Innodb_row_lock%';
-- 分析 SQL
explain select ...;
-- 查看慢查询配置
show variables like 'slow_query%';
show variables like 'long_query_time';
-- 查看主从状态
show slave status\G
四、典型故障场景
-
数据库突然卡顿
- 长事务锁表 → 杀事务
- 慢 SQL 耗尽 IO/CPU → 杀掉并优化
- 磁盘 IO 100% → 检查是否有大量排序、临时表
-
数据库宕机重启
- 查看错误日志定位崩溃原因
- 检查 OOM、磁盘满、文件损坏
- 必要时使用备份恢复
-
从库延迟严重
- 大事务(如 delete 大量数据)
- 从库配置过低、无索引
- 并行复制参数未优化
-
磁盘空间暴涨
- binlog 未清理 → 配置 expire_logs_days
- 临时表、undo 空间异常
- 大表无归档清理
五、优化总结
- 优先解决慢 SQL 与索引缺失,见效最快。
- InnoDB 缓冲池是性能核心,合理分配内存。
- 避免长事务、大事务,减少锁竞争。
- 做好监控与日志,故障可快速定位。
- 定期备份,故障时能快速恢复。