mysqldump 备份失败时常见 exit code 为 2(连接拒绝/认证失败)、3(表不存在或权限不足)、11(i/o 错误或磁盘满);成功为 0,需根据具体错误码决定是否重试。

mysqldump 备份失败时 exit code 是多少
mysql 备份失败不会抛出异常,而是靠 mysqldump 进程退出码判断成败。成功是 0,常见失败码: 2(连接拒绝/认证失败)、3(表不存在或权限不足)、11(I/O 错误或磁盘满)。忽略退出码直接重试,等于对权限错误、SQL 语法错也盲目重试,反而掩盖真问题。
实操建议:
- 每次执行
mysqldump后立刻检查$?,只对2(临时性连接失败)和11(短暂 I/O 拥塞)重试 - 遇到
3、4、5等码直接退出,这类是配置或权限问题,重试无意义 - 用
set -e会干扰判断,必须显式捕获退出码
shell 循环重试的正确写法(带退避)
简单 while true 不行:网络抖动可能持续几秒,但连续毫秒级重试只会加剧服务压力,还可能触发 MySQL 的连接拒绝策略(如 max_connect_errors)。必须加延迟 + 递增退避。
实操建议:
- 初始延迟 1 秒,每次失败翻倍,上限设为 30 秒(避免单次卡死太久)
- 最多重试 5 次,再失败就放弃,把日志和当前
$?写入监控告警通道 - 命令中必须加
--single-transaction --routines --triggers,否则并发写入时 dump 可能不一致
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 挂载中断,重定向 > file.sql 会静默失败,而 mysqldump 自己并不感知。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
实操建议:
- 每次 dump 后立刻用
ls -l和stat检查文件大小是否 > 0,且 mtime 在 5 秒内 - 用
dd if=/dev/zero of=testfile bs=1M count=100提前测试目标路径可写性和空间余量 - 不要用
tee或管道替代重定向——管道失败时mysqldump可能被 SIGPIPE 终止,退出码变成 141,难以归类
crontab 里跑重试脚本要注意 PATH 和环境变量
crontab 默认 PATH=/usr/bin:/bin,很多发行版把 mysqldump 装在 /usr/local/mysql/bin/,结果脚本找不到命令,重试逻辑根本没触发,日志里只有一行 “command not found”。更隐蔽的是 ~/.my.cnf 在 cron 下不生效,密码得硬编码或用 --defaults-extra-file 显式指定。
实操建议:
- 脚本开头固定写
PATH=/usr/local/mysql/bin:/usr/bin:/bin - 用
--defaults-extra-file=/etc/mysql/backup.cnf管理凭证,该文件权限必须是600,且属主是运行 cron 的用户 - 在 crontab 条目里加
SHELL=/bin/bash和完整绝对路径,例如:0 2 * * * SHELL=/bin/bash /opt/scripts/backup_retry.sh
重试不是万能解药。连接超时、DNS 解析失败、SSL 握手异常这些网络层问题适合重试;但账号过期、max_allowed_packet 不够、从库 SQL 线程停摆,重试只会重复失败。关键在区分错误类型,而不是堆次数。










