最靠谱的是mysql的error log,需先用grep查log_error配置,无结果则找数据目录下的hostname.err;常见原因包括端口冲突、innodb文件被占用、配置文件权限过宽,排查时应前台启动并检查selinux/apparmor及磁盘空间。

看哪个日志文件最靠谱
MySQL启动失败时,错误几乎一定写进了error log,而不是终端或systemctl status输出里。别猜路径,直接查配置:grep -i "log_error" /etc/my.cnf /etc/mysql/my.cnf /usr/my.cnf 2>/dev/null。如果没结果,就去数据目录找hostname.err(比如localhost.err),这是MySQL的fallback行为。
常见坑:有人改过datadir但忘了同步log_error路径,或者SELinux/AppArmor静默拦截后日志只写半截,看着像“没日志”——其实有,只是权限不够读不到。临时验证可跑:sudo -u mysql tail -n 20 /var/lib/mysql/localhost.err。
端口被占、权限错、配置语法错,三类高频原因
打开日志后,盯住这几行:
-
Can't start server: Bind on TCP/IP port: Address already in use→ 端口冲突。用sudo lsof -i :3306查进程,不是所有占用都该杀——Docker容器、旧mysqld残留、甚至另一个MySQL实例都可能在那儿。 -
InnoDB: Unable to lock ./ibdata1 error: 11→ 不是磁盘坏了,是还有个mysqld在跑。别急着删文件,先ps aux | grep mysqld,确认无残留再操作。 -
World-writable config file '/etc/my.cnf' is ignored→ 配置文件权限太宽(比如777),MySQL直接跳过它,然后按默认路径找数据目录,自然找不到mysql.plugin表。修复只需sudo chmod 644 /etc/my.cnf。
绕过mysqld_safe,直接前台启动看真错误
很多系统用mysqld_safe包装启动,它会自动重启崩溃进程,把原始错误盖住了。想看清问题,就停服务后手动前台运行:
sudo systemctl stop mysqlsudo -u mysql mysqld --user=mysql --datadir=/var/lib/mysql --basedir=/usr --console
这时所有报错——包括my.cnf里多了一个逗号、plugin_dir路径不存在、甚至chown漏了mysql用户——都会直接打在终端上。注意:路径必须和实际一致,/var/lib/mysql和/usr不能硬套。
别忽略SELinux/AppArmor和磁盘空间
Linux上最隐蔽的两类失败:一是安全模块拦截,日志只写Permission denied,不提SELinux;二是df -h发现/var或/tmp满,但MySQL报错里根本没提“disk full”,只卡在Can't create/write to file '/tmp/ibfguTtC'这种模糊提示。
快速验证是否是它们导致的:
- SELinux临时关:
sudo setenforce 0(CentOS/RHEL) - AppArmor临时停:
sudo systemctl stop apparmor(Ubuntu/Debian) - 磁盘空间检查:
df -h /var /tmp /var/lib/mysql,尤其注意/tmp——InnoDB初始化时会往这儿写临时文件
这些不是“偶尔出问题”,而是上线前最容易漏掉的检查项。一旦服务跑起来,再开回来就行,但排查阶段必须先排除它们。










