其他

1. 代码质量检查

dbbot 的 YAML 建议在提交前执行 lint:

sh lint_all_yml_files.sh

如果仓库存在 .ansible-lint,请以该文件中的忽略规则为准。

2. 常见故障排查

2.1 MySQL 服务重启次数过多导致无法再次启动

如果你在测试 dbbot 部署出来的 mysql3306.service 时,连续多次启动失败,最终会看到下面这种状态:

systemctl status mysql3306.service --no-pager -l
× mysql3306.service - MySQL Server
     Loaded: loaded (/usr/lib/systemd/system/mysql3306.service; enabled; preset: disabled)
     Active: failed (Result: exit-code)
...
Mar 20 02:27:30 systemd[1]: mysql3306.service: Main process exited, code=exited, status=1/FAILURE
Mar 20 02:27:32 systemd[1]: mysql3306.service: Start request repeated too quickly.
Mar 20 02:27:32 systemd[1]: Failed to start MySQL Server.

这不是新的根因,而是 systemd 的保护机制已经生效。dbbot 默认把 MySQL service 配成失败重启,但 5 分钟内只允许异常拉起 2 次,超过后直接停住,避免 mysqld 在配置错误或环境异常时无限重复拉起,把首个真实报错刷掉,拖慢告警确认和人工介入。

你可以直接看 dbbot 部署出来的 service 配置:

systemctl show mysql3306.service -p Restart -p StartLimitIntervalUSec -p StartLimitBurst
Restart=on-failure
StartLimitIntervalUSec=5min
StartLimitBurst=2

实际的启动信息流通常是这样:

journalctl -u mysql3306.service -n 20 --no-pager
Mar 20 02:27:22 systemd[1]: Started MySQL Server.
Mar 20 02:27:25 systemd[1]: mysql3306.service: Main process exited, code=exited, status=1/FAILURE
Mar 20 02:27:27 systemd[1]: Started MySQL Server.
Mar 20 02:27:30 systemd[1]: mysql3306.service: Main process exited, code=exited, status=1/FAILURE
Mar 20 02:27:32 systemd[1]: mysql3306.service: Start request repeated too quickly.
Mar 20 02:27:32 systemd[1]: Failed to start MySQL Server.

遇到这种情况,先查第一次失败的真正原因,不要只盯着 start-limit-hit

journalctl -u mysql3306.service -n 50 --no-pager

常见根因包括 my.cnf 配置错误、端口被占用、目录权限异常、依赖库缺失、安装包路径错误等。

如果只是测试时把服务打进了限流,且根因已经修正,可以这样清零计数并恢复服务:

systemctl reset-failed mysql3306.service
systemctl start mysql3306.service
systemctl status mysql3306.service --no-pager -l

如果你改过 unit 文件,再先执行:

systemctl daemon-reload
systemctl reset-failed mysql3306.service
systemctl start mysql3306.service

2.2 下载 dbbot 或 MySQL 包时报 SSL 证书时间错误

典型报错包括:certificate is not yet validcertificate has expiredCERTIFICATE_VERIFY_FAILED

这类问题首先要怀疑系统时间,不要先去关闭 SSL 校验。

如何快速判断是不是时间问题

先看本机时间和 NTP 状态:

date -R
timedatectl status
chronyc tracking

实测输出片段:

Fri, 20 Mar 2026 02:04:09 +0800
System clock synchronized: yes
NTP service: active
System time     : 0.004828646 seconds slow of NTP time

再看目标站点证书的有效期窗口:

echo | openssl s_client -connect github.com:443 -servername github.com 2>/dev/null | openssl x509 -noout -subject -issuer -dates

实测输出:

subject=CN=github.com
issuer=C=GB, O=Sectigo Limited, CN=Sectigo Public Server Authentication CA DV E36
notBefore=Mar  6 00:00:00 2026 GMT
notAfter=Jun  3 23:59:59 2026 GMT

如果本机时间早于 notBefore 或晚于 notAfterwgetcurl 和 playbook 里的 HTTPS 下载都会报证书时间相关错误。

时间正常时,curl -I 应该能拿到正常响应头,例如:

curl -I https://github.com
HTTP/2 200
date: Thu, 19 Mar 2026 18:05:47 GMT
strict-transport-security: max-age=31536000; includeSubdomains; preload

推荐处理方式

在 Rocky 9 / RHEL 9 上优先使用 chronyd

timedatectl set-ntp true
systemctl restart chronyd
chronyc -a makestep
date -R
chronyc tracking

较老系统如果仍使用 ntpdate,再执行:

ntpdate pool.ntp.org

时间修正后,再重新执行下载或 playbook。

不要用 wget --no-check-certificatecurl -k 把问题掩盖掉,先把系统时间校准。

3. 建议

  • 部署前先做时间同步和网络连通性检查。
  • 生产环境谨慎直接修改 systemd 限流参数,优先确认根因。
  • 高风险操作前建议快照或备份。