mysql进程意外退出后systemd未重启,需配置restart=on-failure并执行daemon-reload;若启动失败循环,应设restartsec和调整startlimitintervalsec;自动重启不解决数据损坏,须人工检查错误日志与innodb状态。

MySQL进程意外退出后 systemd 没重启,检查 Restart= 配置是否生效
systemd 默认不会自动重启服务,必须显式配置重启策略。常见错误是只改了 mysqld.service 文件却没重载配置,或用了不匹配的 Restart= 值。
-
Restart=no(默认值):进程退出后不重启,哪怕崩溃也静默停止 - 生产环境应设为
Restart=on-failure:仅在非正常退出(如被 kill -9、段错误、崩溃)时重启;always会连正常systemctl stop都触发重启,反而干扰运维 - 改完必须执行
sudo systemctl daemon-reload,否则systemctl cat mysqld看到的仍是旧配置 - 验证是否生效:
sudo systemctl show mysqld | grep Restart,输出应为Restart=on-failure
MySQL启动失败导致反复重启循环,检查 RestartSec 和 StartLimitIntervalSec
如果 MySQL 因配置错误、磁盘满、端口被占等原因无法真正启动,systemd 会在短时间内反复拉起又失败,触发速率限制,最终标记服务为 failed 并彻底放弃重启。
- 默认 10 秒内最多启动 5 次(
StartLimitIntervalSec=10+StartLimitBurst=5),超限后systemctl start mysqld直接报错Failed to start mysqld.service: Start request repeated too quickly. - 加
RestartSec=5(建议 3–10 秒)让每次重启前等几秒,避免雪崩式重试 - 临时放宽限制可加
StartLimitIntervalSec=0(禁用限频),但仅用于排查,上线前务必恢复 - 查失败原因优先看:
sudo journalctl -u mysqld -n 50 -e,重点找Can't start server、Address already in use、InnoDB initialization failed这类错误行
MySQL崩溃后数据损坏风险仍在,Restart=on-failure 不等于高可用
自动重启只是把进程拉起来,掩盖不了根本问题。若 MySQL 因写坏页、日志断裂、磁盘 I/O 错误而崩溃,重启后可能直接卡在 recovery 阶段,甚至进入只读状态或拒绝启动。
- 确认崩溃类型:
sudo journalctl -u mysqld | grep -i "crash\|segfault\|signal 11\|InnoDB: Database page corruption" - 关键检查项:
innodb_force_recovery值是否被误设(非调试勿动)、datadir所在分区是否只读或空间不足(df -h /var/lib/mysql)、/var/log/mysql/error.log是否有Corrupted log block - 自动重启不能替代备份恢复流程。只要发生过非预期退出,必须人工确认
mysqlcheck --all-databases --check或至少SHOW ENGINE INNODB STATUS\G中无严重警告
修改 systemd 配置时绕过包管理器覆盖风险
直接编辑 /usr/lib/systemd/system/mysqld.service 是危险操作,下次 mysql-community-server 升级时会被 rpm/deb 包强制覆盖,导致自动重启失效。
- 正确做法是创建覆盖片段:
sudo systemctl edit mysqld,它会生成/etc/systemd/system/mysqld.service.d/override.conf - 在这个文件里只写要改的部分,例如:
[Service] Restart=on-failure RestartSec=5 StartLimitIntervalSec=60 StartLimitBurst=3
- 片段方式不受上游包更新影响,且
systemctl cat mysqld会清晰显示哪些配置来自哪里 - 切勿在
/etc/systemd/system/mysqld.service全量复制原文件——这会完全接管服务定义,后续升级可能丢失新特性或安全修复
自动重启只是兜底动作,真正关键的是搞清为什么崩:是内存 OOM 被 kernel 杀掉?还是慢查询拖垮连接池导致 accept 队列溢出?这些得从 journalctl 和 MySQL 自身 slow log、error log 里交叉比对。重启配置写对了,日志不看,照样救不回数据。











