MySQL服务在systemd下必须显式配置Restart=on-failure、RestartSec、StartLimit*及MemoryLimit等资源限制,否则崩溃后静默退出、OOM被杀或IO打满拖垮整机;自动重启不修复数据损坏,须人工核查错误日志与InnoDB状态。

MySQL服务在systemd下必须显式配置重启策略和资源限制,否则崩溃后静默退出、OOM时被kill、IO打满拖垮整机都是大概率事件。
Restart=on-failure 是生产环境唯一合理的选择
systemd默认Restart=no,进程一退出就停着,连段错误都不管。设成Restart=always更危险——systemctl stop mysqld也会立刻被拉起,运维操作直接失效。
正确做法是:
- 用
Restart=on-failure:仅对非零退出码、信号终止(如SIGSEGV、SIGKILL)触发重启 - 加
RestartPreventExitStatus=1:避免mysqld启动校验失败(比如配置语法错)时也重启,防止陷入启动-失败-重启死循环 - 改完必须执行
sudo systemctl daemon-reload,否则systemctl show mysqld | grep Restart看到的还是旧值
内存与IO过载时 systemd 会直接杀掉 mysqld
MySQL没配MemoryLimit或IOWeight,一旦遇到大查询或并发写入,可能吃光内存触发OOM Killer,或者IO占满导致其他服务卡死。
关键限制项应加在[Service]节里:
监控 Victron Energy 电力系统,生成包含电池状态、光伏发电量和活动警报的精美每日邮件报告。集成 Vic...
-
MemoryLimit=4G:硬限制RSS内存,超限后systemd发SIGKILL(比内核OOM Killer更可控) -
IOWeight=50:在cgroup v2环境下限制IO权重,避免MySQL独占磁盘带宽 -
LimitNOFILE=65535:不加这个,连接数稍高就会报Too many open files - 所有限制修改后需
sudo systemctl daemon-reload & sudo systemctl restart mysqld
反复启动失败时 systemd 会彻底放弃,必须调StartLimit*参数
MySQL因datadir权限错、端口被占、innodb_force_recovery误开等原因无法完成初始化,systemd默认10秒内最多启动5次,之后就标记failed并拒绝再试。
排查和缓解步骤:
- 先看日志:
sudo journalctl -u mysqld -n 50 -e,重点搜Address already in use、InnoDB initialization failed、Can't open shared library - 临时放宽限制:
StartLimitIntervalSec=0(禁用频控),仅用于定位问题,切勿长期启用 - 加
RestartSec=5:每次失败后等5秒再试,避免日志刷屏和磁盘IO雪崩 - 确认
StartLimitBurst=3和StartLimitIntervalSec=60组合合理(即1分钟内最多重试3次)
自动重启不修复数据损坏,错误日志和InnoDB状态必须人工确认
Restart=on-failure只是把进程拉起来,掩盖不了底层问题。如果MySQL因InnoDB: Database page corruption或log block checksum mismatch崩溃,重启后可能卡在恢复阶段,甚至进入只读模式。
每次非预期退出后必须手动检查:
sudo journalctl -u mysqld | grep -i "crash\|segfault\|signal 11"-
sudo tail -n 100 /var/log/mysql/error.log,找Corrupted、redo log、ibdata1相关行 -
df -h /var/lib/mysql确认磁盘没满,ls -l /var/lib/mysql确认ib_logfile*可写 - 运行
mysqlcheck --all-databases --check,而非依赖自动重启“假装没事”
真正麻烦的从来不是服务起不来,而是它起来了,但数据已经不对了。

















