做了这么多年后端开发,MySQL出的问题基本可以归为几类。每次排障花大量时间翻日志找原因,不如把常见故障的处理方案整理出来。下面是我个人遇到频率最高的五个MySQL问题,以及排查思路。
Q1:客户端报"Too many connections"
这个错误是MySQL连接数达到max_connections上限了。我遇到的最多两个原因:
一是应用层没有复用连接。PHP-FPM每次请求都new一个连接,流量高峰时瞬间打满。解决方案:检查应用代码里是否用了连接池(PHP用persistent connection、Go用sql.DB连接池、Python用SQLAlchemy连接池)。设连接池最大连接数为max_connections的60%-70%,留够buffer。
二是慢查询堆积。一个查询跑了30秒,连接不释放,后面的请求排队等新连接,越积越多。先用SHOW PROCESSLIST看有没有长时间Running的查询,找到后KILL掉。然后去慢查询日志里找对应的SQL优化。
紧急处理:SET GLOBAL max_connections = 300;临时提高上限(比默认151翻一倍)。但这是止痛药,根因还是要查连接池和慢查询。
Q2:数据库突然变慢,CPU飙高
2026年最常见的原因是没建索引或索引失效。排查步骤:
SHOW FULL PROCESSLIST; 看当前运行的查询,找出执行时间长的。
EXPLAIN SELECT ... 看执行计划。如果type列是ALL(全表扫描)且rows很大,说明索引问题。常见坑:WHERE条件用了LIKE '%keyword'(前缀模糊导致索引失效)、用了函数包裹索引列(WHERE DATE(created_at) = '2026-08-01'改成WHERE created_at >= '2026-08-01' AND created_at < '2026-08-02')、JOIN的字段类型不一致导致隐式转换不走索引。
另一个容易被忽略的原因是innodb_buffer_pool_size太小。这个参数控制InnoDB在内存里缓存多少数据和索引。如果buffer pool太小(比如默认128MB),大量查询需要读磁盘,CPU等IO时看起来高但其实是IO瓶颈。设置成物理内存的70%-80%(专用数据库服务器的情况)。
Q3:Can't connect to MySQL server on 'localhost'
最常见的情况:MySQL没启动。看状态:systemctl status mysql或systemctl status mysqld。
启动了但连不上:检查MySQL绑定的地址。SHOW VARIABLES LIKE 'bind_address';如果显示127.0.0.1,说明只接受本地连接。改成0.0.0.0或具体IP。
能连但报Access denied:检查用户名、密码、host。MySQL的用户是username@host的组合,'myuser'@'localhost'和'myuser'@'%'是两个不同的账户。PHP连接用localhost时走的是socket而非TCP,权限可能不同。
2026年宝塔面板用户常见的坑:面板里改了MySQL root密码,但面板和MySQL实际密码不同步。需要进终端手动重置。
Q4:磁盘空间突然满了
一般是binlog堆积。MySQL 8.0+默认开binlog,每个文件1GB,不清理的话几天就能占几十GB。检查:SHOW BINARY LOGS;看有多少文件。
清理:PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);删除7天前的binlog。
长期方案:在my.cnf里设binlog_expire_logs_seconds = 604800(7天自动清理)。
另一个常见原因是ibdata1文件膨胀。如果用了innodb_file_per_table=OFF(MySQL 5.x的默认),所有表共用一个ibdata1,删表不释放空间。MySQL 8.0默认innodb_file_per_table=ON,每个表独立文件,删表即释放。如果还在用老配置,赶紧改。
Q5:数据误删了怎么恢复
误删数据后第一件事不是恢复,是立即停止写入。如果数据库还在写入,被删数据所在的磁盘位置可能被覆盖。
恢复方案取决于你有哪些备份:有全量备份+binlog→用全量备份恢复,再用binlog重放到误删前的时刻(mysqlbinlog --stop-datetime="2026-08-01 10:30:00")。只有全量备份没有binlog→只能恢复到备份时间点,之后的数据永久丢失。没有备份也没有binlog→大概率无法恢复(可以试试磁盘恢复工具但成功率不高)。
预防方案很简单:开启binlog、每天定时备份(mysqldump或xtrabackup)、备份文件存到不同于数据库服务器的位置。我现在的配置:每天凌晨3点xtrabackup全量备份+每小时binlog备份,都上传到阿里云OSS。成本一个月大约15块钱——对比一次数据丢失的代价,便宜得像不要钱。
还木有评论哦,快来抢沙发吧~