mysql频繁重启主因是外部约束或配置失配触发系统保护(如oom killer)或自愈逻辑;需据错误日志区分启动失败还是运行中崩溃,重点核查内存参数总和是否超限、磁盘空间、pid目录权限及systemd限制,并优先停自动重启、安全启动后立即备份。

先看 systemd 日志里有没有 Restart=on-failure 的痕迹
MySQL 自己不会半夜“主动重启”,所谓神秘挂掉,99% 是 systemd 在背后兜底拉起。重点不是查 MySQL 挂没挂,而是查它被谁杀、为什么被杀、又被谁拉起来。
执行:sudo journalctl -u mysql --since "2 days ago" | grep -E "(started|stopped|exited|killed|signal|OOM|restart)"
- 如果看到
exited with code 137或Received SIGKILL,基本锁定 OOM 或外部 kill - 如果看到反复出现
Started MySQL Server→Stopped MySQL Server→ 再Started,说明 systemd 配置了Restart=on-failure甚至Restart=always - 注意时间戳是否集中在凌晨 2–4 点——很多定时任务(如 logrotate、备份脚本、监控巡检)在这个时段运行,可能误杀或触发资源争抢
用 dmesg 和 kern.log 锁定是不是被 OOM Killer 干掉的
MySQL 崩溃时往往来不及写完整错误日志,但内核会记一笔。只要它是被 kill -9 或 OOM Killer 终止,dmesg 或 /var/log/kern.log 一定有记录。
执行:dmesg -T | grep -i "killed process.*mysqld"
- 输出类似
Killed process 12345 (mysqld) total-vm:4234567kB, anon-rss:1890123kB, file-rss:0kB, shmem-rss:0kB→ 就是 OOM - 没结果?再查:
sudo grep -i -E "(oom|kill|memory)" /var/log/kern.log | tail -20 - 特别注意
score值:分数越高越容易被杀;如果mysqldscore 远高于其他进程,说明它吃内存太猛,不是偶然,是常态
翻 MySQL error.log 要盯住“最后一行”和“启动前报错”
别只扫 tail -n 50,要结合重启时间反推——找每次重启前 30 秒内的最后几条日志。很多致命问题就藏在“准备关闭”之前。
先确认日志位置:mysql -e "SHOW VARIABLES LIKE 'log_error';"
- 常见关键线索:
Cannot allocate memory for the buffer pool(配置超限)、InnoDB: Database page corruption(磁盘或断电损坏)、Table 'xxx' is marked as crashed(MyISAM 表损坏) - 如果日志里只有
mysqld: ready for connections和Shutting down,没有中间报错 → 基本排除 MySQL 自身逻辑崩溃,指向外部强制终止 - 留意
Aborted connection是否暴增——可能是应用层连接泄漏,积累到半夜触发资源耗尽
检查磁盘空间和 PID 目录权限这类“启动即跪”的硬伤
半夜挂掉也可能是启动失败后 systemd 循环重试造成的“假重启”。MySQL 根本没跑起来,只是反复尝试进门失败。
- 查磁盘:
df -h /var/lib/mysql(或你的 datadir 所在分区),满或只剩 - 查 PID 目录:
ls -ld /var/run/mysqld/,确认目录存在且mysql用户有写权限;不存在就手动建 +chown mysql:mysql - 查文件句柄:
cat /proc/$(pgrep mysqld)/limits | grep "Max open files",若显示1024,而max_connections设了 500+,大概率半夜高并发时撑不住
真正难缠的点不在日志语法,而在时间差——系统日志、MySQL 日志、journalctl 的时间戳经常不同步,得靠“重启时刻”对齐三者,才能分清是崩在启动中、运行中,还是刚启动完就被掐了。











