数据库备份任务成功与否需多重验证:检查文件大小、mysqldump退出码、磁盘空间,并用sendmail或宝塔api发送带主机名、库名、日志路径的utf-8编码告警。

数据库备份任务是否成功,不能只看计划任务有没有执行
宝塔面板的「计划任务」里哪怕显示“执行成功”,也只代表脚本跑完了,不代表 mysqldump 没报错、备份文件没写空、磁盘没满、权限没丢。真实失败常表现为:backup.sql 文件大小为 0 字节、mysqldump: Got error: 1045、No space left on device 错误被静默吞掉。必须在脚本里显式检查关键信号。
- 每次备份后立刻用
ls -l /path/to/backup/*.sql | awk '{print $5}'检查文件体积,小于 1024 字节就判定失败 - 捕获
mysqldump的退出码:if [ $? -ne 0 ]; then ...,不能只靠&&链式执行 - 备份前加
df -h /www/backup | awk 'NR==2 {print $5}' | tr -d '%'判断剩余空间,低于 15% 就跳过并告警
用 mail 命令发通知时,中文乱码和退信率高
直接 echo "备份失败" | mail -s "告警" admin@x.com 在多数服务器上会触发 UTF-8 编码缺失,导致收件箱显示问号或被当垃圾邮件拦截。根本原因是 mail 工具默认不声明字符集与 MIME 类型。
- 改用
sendmail构造完整邮件头:printf "To: admin@x.com\nSubject: =?UTF-8?B?5byg5LiJ55Sf?= \nContent-Type: text/plain; charset=UTF-8\n\n备份失败,请检查 /www/backup/" | sendmail -t - 若用
mailx,必须提前设置:export MAILX=/usr/bin/mailx并在脚本开头加set sendcharsets=utf-8 - 更稳妥的做法是调用宝塔内置 API:
curl -X POST http://127.0.0.1:8888/mail/send -H "Authorization: Bearer YOUR_TOKEN" -d "to=admin@x.com" -d "subject=数据库备份异常" -d "content=$(date): 备份文件为空",它自动处理编码与 SPF 记录校验
如何让通知包含可定位的上下文信息
光说“备份失败”没用,运维人员得立刻知道是哪个库、哪个时间点、哪台服务器出的问题。日志路径、数据库名、主机名这些字段必须硬编码进通知内容,不能依赖外部变量临时拼接。
- 在备份脚本里固定写入:
DB_NAME="wordpress"、HOSTNAME="$(hostname -s)"、LOG_PATH="/www/wwwlogs/mysql_backup.log" - 通知正文模板示例:
【${HOSTNAME}】${DB_NAME} 库备份失败(${LOG_PATH} 第 $(tail -n 1 ${LOG_PATH} | wc -l) 行) - 避免用
$(date +%F_%H:%M)这类动态时间戳——如果脚本卡在某步,时间会失真;改用BEGIN_TIME=$(date +%s)+END_TIME=$(date +%s)算耗时,更可靠
宝塔计划任务里粘贴脚本,换行和引号容易被吃掉
宝塔面板的「Shell脚本」计划任务输入框对特殊字符极其敏感。复制粘贴时,Windows 换行符 \r\n、中文引号、缩进空格都会导致语法错误,且错误不报在面板界面,只出现在 /var/log/cron 里写 bad hour 或 syntax error near unexpected token `then'。
- 所有脚本必须先用
dos2unix清理换行:echo 'your script' | dos2unix | tee /tmp/backup.sh - 单引号内的字符串禁止换行,长命令拆成多行时用反斜杠
\续行,且反斜杠后不能有空格 - 测试脚本是否能在计划任务环境运行:
env -i PATH=/usr/bin:/bin /bin/bash -c "source /etc/profile; /tmp/backup.sh",模拟最小化环境
~/.my.cnf(计划任务以 root 用户运行,读不到普通用户家目录)。必须用 mysql_config_editor 创建 login path,并在脚本中用 --login-path=prod 调用,否则一升级宝塔或重装系统,备份就永久中断。











