先别慌,也别急着网上搜到“删 ib_logfile”就动手,那是最后一步,搞错了数据直接没。按下面这个顺序走,90% 的宝塔 MySQL 起不来都能定位到。
第一步:先看磁盘,这个最容易被忽略
df -h
df -i
磁盘 100% 或者 inode 满了,MySQL 必然起不来,日志里还会莫名其妙报 InnoDB 写入失败、表空间损坏,看着像数据坏了其实不是。宝塔的日志、临时文件、备份堆满 / 是重灾区。真是满了就先清空间再启动,别修数据库。
第二步:看有没有残留进程占着 3306
ps aux | grep mysql
ss -lntp | grep 3306
经常是上次崩了没死透,或者面板点了几次启动,堆了两三个 mysqld 进程,互相抢端口。把 grep 出来的 mysql 进程全 kill 掉(kill -9 进程号),尤其是 mysqld_safe,然后回面板重新启动。注意别把面板自己的 python 进程误杀。
第三步:翻日志最后 50 行,只看最后一条致命错误
tail -n 100 /www/server/data/*.err
别整个文件通读,直接拉到最底下。找带 [ERROR]、FATAL、InnoDB: 的那几行,MySQL 挂掉的原因基本就在最末尾那一条。
常见的几种对应关系:
- 报
Another process...或Can't start server: Bind on TCP/IP port→ 回第二步杀进程。 - 报
Database page corruption on disk/tablespace is missing→ 数据页损坏,往下看第五步。 - 报
log file ./ib_logfile0 is of different size→ 是 ib_logfile 和数据不匹配,这种别乱删,先备份整个 data 目录再说。 - 日志完全是空的 → 大概率是参数问题(见第四步),或者磁盘满、用户不存在。
- 报
InnoDB: Cannot allocate memory→ 内存不够,小机器把 innodb_buffer_pool_size 调太大了,改小。
第四步:参数被改坏了,宝塔高频坑
如果你前几天在面板的「MySQL → 性能调整」里点过保存,或者改过最大连接数之类,八成是这里。那个页面保存有时会把 my.cnf 写残缺,MySQL 就起不来了。
cat /etc/my.cnf
看有没有明显缺项或者奇怪的值(比如 thread_stat 写成小数)。新手最快的办法:把性能调整里的参数恢复默认,或者用同版本 MySQL 的默认 my.cnf 覆盖掉,再启动。同时顺手检查:
ls -ld /www/server/data
id mysql
data 目录属主必须是 mysql:mysql;还有 /etc/passwd 里得存在 mysql 这个用户,手动清理系统时误删用户也起不来。权限不对就 chown -R mysql:mysql /www/server/data。
第五步:确认是数据损坏,用强制恢复顶起来救数据
日志明确是 InnoDB 页面损坏、系统表空间错误,走这条路:
**先在 /etc/my.cnf 的 [mysqld] 下面加:**
innodb_force_recovery = 1
从 1 开始试,起不来就 2、3、4,一般到 4 就能起来(6 是极限,会变成只读,能起来就偷着乐)。一旦能起来,第一件事不是继续用,是立刻全量导出:
mysqldump -uroot -p --all-databases > /root/all_backup.sql
或者直接打包 /www/server/data 整个目录留底。导出完再查是哪个表坏了,CHECK TABLE 表名; 看结果,MyISAM 表可以 REPAIR TABLE,InnoDB 基本就是 dump 出来、重建库、再导回去。
动手前的保命动作:cp -a /www/server/data /root/data_bak_日期,或者 tar 一份存到别的盘。数据损坏这种事儿,试错空间全靠这一份备份。
一句话记住顺序:先 df -h 看盘 → 再看进程和端口 → 然后 tail 日志末行定位 → 再查参数和权限 → 最后才是走 innodb_force_recovery 抢数据。前面几项没问题,别一上来就去修表,越修越糟。