必须通过原子化标记文件暴露自定义指标:mysql_backup_last_success_seconds_ago(距上次成功秒数)和mysql_backup_last_duration_seconds(本次耗时),并用双条件告警(如>3900s且<86400s)同时校验备份状态与时效性。

原生 mysqld_exporter 完全无法获取 MySQL 备份任务的时长或状态——它连备份脚本是否存在都不知道,更别提读取退出码、解析日志或检查文件时间戳。必须通过外部标记 + 自定义指标暴露的方式,把备份结果“翻译”成 Prometheus 能理解的数字。
备份状态不能靠 mysql_up 或文件 mtime 判断
常见错误是误用已有指标:比如用 mysql_up == 1 当作备份成功,或用 node_filesystem_mtime_seconds{mountpoint="/backup"} 监控目录修改时间。这两种方式都会漏判:
-
mysql_up只反映 MySQL 实例是否可连接,xtrabackup 卡死、mysqldump权限失败、磁盘写满导致生成空文件时,MySQL 仍可能返回1 -
mtime无法区分“备份进程刚启动但尚未写完”和“备份已成功完成”,尤其在大库场景下,备份耗时几十分钟,仅靠 mtime 会频繁误告 - 日志关键词匹配(如用 Loki 查
"completed OK")延迟高、无原子性,且无法与 Prometheus 告警规则直接联动
用原子化标记文件暴露 mysql_backup_last_success_seconds_ago
核心做法是在备份脚本末尾写入一个带时间戳的标记文件,并确保写入操作是原子的(避免写到一半被中断)。然后让自定义 collector 读取该文件并计算距今秒数。
- 备份脚本结尾加:
if [ $? -eq 0 ]; then echo $(date +%s) > /var/lib/mysql-backup/last_success_timestamp fi
- 标记文件路径必须可被 exporter 进程读取(注意 SELinux 和文件权限)
- collector 暴露的指标名建议统一为
mysql_backup_last_success_seconds_ago,类型为 Gauge,值为$(date +%s) - $(cat /var/lib/mysql-backup/last_success_timestamp) - 不要用
stat -c %Y获取 mtime,因为文件系统精度可能低于秒,且 NFS 等环境存在缓存偏差
备份时长指标需独立采集,不能复用 last_success_seconds_ago
mysql_backup_last_success_seconds_ago 表示“上次成功距今多久”,它不能告诉你本次花了多少时间。要监控时长,必须在备份开始前记录起始时间,成功后写入耗时。
- 备份脚本开头加:
echo $(date +%s) > /var/lib/mysql-backup/backup_start_timestamp
- 结尾成功分支里加:
START=$(cat /var/lib/mysql-backup/backup_start_timestamp 2>/dev/null) DURATION=$(( $(date +%s) - START )) echo $DURATION > /var/lib/mysql-backup/last_duration_seconds
- 对应 collector 暴露
mysql_backup_last_duration_seconds,Grafana 面板中可用max_over_time(mysql_backup_last_duration_seconds[7d])观察历史峰值 - 若备份失败,不覆盖
last_duration_seconds,这样 Prometheus 中该指标会保持旧值,配合告警规则可识别“长时间未更新”
告警规则必须同时检查状态与时效性
只盯 mysql_backup_last_success_seconds_ago > 3600 会忽略“备份持续失败但每次都在重试”的情况;只盯 mysql_backup_last_duration_seconds 又无法发现“根本没跑起来”的问题。
- 推荐双条件告警:
ALERT MySQLBackupStalled IF mysql_backup_last_success_seconds_ago > 3900 AND mysql_backup_last_success_seconds_ago < 86400 FOR 10m LABELS { severity = "warning" } ANNOTATIONS { summary = "MySQL backup hasn't succeeded for over 1h" } -
< 86400是为了排除“备份彻底停摆多日”的场景,这种应走另一条更紧急的告警路径 - 如果使用
xtrabackup,还可加一层:监控ps aux | grep xtrabackup进程是否存在,用node_systemd_unit_state{name="xtrabackup-backup.service"} == 0配合 systemd,防止脚本卡死不退出
真正难的不是写 exporter,而是让备份脚本本身具备可观测性:退出码、时间戳、原子写入、错误隔离——这些细节一旦松动,Prometheus 就只能看到一堆“看起来正常”的数字,而实际备份早已静默失效。


















