mysqldump 备份失败如何自动重试:编写循环重试逻辑 mysqldump 备份失败时 exit code 是多少 处理 MySQL 备份,有个细节很容易被忽略:mysqldump 命令本身并不会抛出异常,成败全靠进程的退出码来判断。成功时,这个码是 0。一旦失败,不同的退出码就像不同的“故障代

处理 MySQL 备份,有个细节很容易被忽略:mysqldump 命令本身并不会抛出异常,成败全靠进程的退出码来判断。成功时,这个码是 0。一旦失败,不同的退出码就像不同的“故障代码”,指向了不同的问题根源。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
常见的几个关键码需要记牢:2 通常意味着连接被拒绝或者认证失败;3 则指向表不存在或权限不足这类问题;而 11,往往是 I/O 错误或磁盘空间已满的信号。如果不管三七二十一,遇到失败就盲目重试,那可就麻烦了。想想看,对权限错误或者 SQL 语法问题反复尝试,不仅解决不了问题,反而会掩盖真正的故障原因,让排查变得更困难。
所以,正确的操作姿势应该是:
mysqldump,立刻检查 $ 变量。只对像 2(可能是临时的网络连接失败)和 11(短暂的 I/O 拥塞)这类具有“临时性”特征的错误码进行重试。3、4、5 这类退出码,就别再尝试了,直接退出脚本。这多半是配置错误或权限问题,重试多少次都是徒劳。set -e 要小心,它可能会干扰退出码的判断逻辑,所以最好还是显式地捕获并处理退出码。写重试逻辑,可不是简单套个 while true 循环就完事了。网络抖动可能持续几秒,如果你用毫秒级的间隔连续重试,不仅会加剧数据库服务的压力,还可能触发 MySQL 的连接拒绝策略(比如 max_connect_errors)。因此,必须引入延迟机制,并且最好是“退避式”的延迟。
具体来说,可以这么设计:
mysqldump 命令时,务必加上 --single-transaction --routines --triggers 这些参数,否则在数据库有并发写入时,导出的数据可能不一致。retry=0
max_retries=5
delay=1
while [ $retry -lt $max_retries ]; do
mysqldump -h db.example.com -u backup_user -p'xxx' mydb > /backup/mydb_$(date +%s).sql 2>/dev/null
exit_code=$
if [ $exit_code -eq 0 ]; then
echo "backup success"
exit 0
elif [ $exit_code -eq 2 ] || [ $exit_code -eq 11 ]; then
echo "retry $retry, sleep $delay sec..."
sleep $delay
retry=$((retry + 1))
delay=$((delay * 2))
[ $delay -gt 30 ] && delay=30
else
echo "fatal error: mysqldump exit $exit_code"
exit $exit_code
fi
done
这里有个更隐蔽的“坑”:即使 mysqldump 进程的退出码是 0,也不代表数据真的安全落盘了。如果目标路径磁盘已满、目录没有写入权限,或者 NFS 挂载突然中断,那么 Shell 的重定向操作 > file.sql 会静默失败,而 mysqldump 命令本身对此一无所知,依然会返回成功。
要避免这种“假成功”,你得在脚本里加上几道保险:
ls -l 和 stat 命令检查生成的备份文件,确认其大小大于 0,并且文件的修改时间在最近几秒内。dd if=/dev/zero of=testfile bs=1M count=100 这样的命令,快速测试一下目标路径的可写性和剩余空间。tee 或管道来替代重定向。因为当管道下游失败时,mysqldump 可能会被 SIGPIPE 信号终止,退出码变成难以归类的 141,让错误处理逻辑变得复杂。把重试脚本放到 crontab 里自动执行,又是另一个容易踩坑的地方。cron 默认的 PATH 环境变量通常只有 /usr/bin:/bin,而很多发行版会把 mysqldump 安装在 /usr/local/mysql/bin/ 这样的路径下。结果就是,脚本根本找不到命令,重试逻辑压根没触发,日志里只会留下一行冷冰冰的 “command not found”。
更隐蔽的问题是,~/.my.cnf 这种配置文件在 cron 环境下是不生效的。密码要么得硬编码在脚本里(不安全),要么就得用 --defaults-extra-file 参数来显式指定一个配置文件。
因此,在 crontab 中部署时,务必注意:
PATH,比如 PATH=/usr/local/mysql/bin:/usr/bin:/bin。--defaults-extra-file=/etc/mysql/backup.cnf 来管理数据库凭证,并确保这个配置文件的权限是 600,且属主是运行 cron 任务的用户。SHELL=/bin/bash 的声明,并使用脚本的绝对路径,例如:0 2 * * * SHELL=/bin/bash /opt/scripts/backup_retry.sh。说到底,重试机制不是万能解药。它擅长应对连接超时、DNS 解析失败、SSL 握手异常这类具有 transient 特性的网络层问题。但对于账号过期、max_allowed_packet 设置不足、或者从库 SQL 线程停摆这类“硬伤”,重试再多次也是徒劳。关键在于精准区分错误类型,对症下药,而不是简单地堆叠重试次数。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述