如何解决mongodump出现服务器连接错误但返回错误码0的问题
问题根本原因
你获取到的退出码实际是管道最后一个命令gzip的退出码,而非mongodump的退出码。Bash 默认管道命令的整体退出码为管道链最后一个命令的退出码,只要gzip本身运行没有异常,不管前面的mongodump执行成功还是失败,你拿到的$?都会是0,这和MongoDB官方的退出码规则并不冲突。
至于为什么mongodump连接失败还会生成备份文件,是因为>重定向操作会在整条命令执行前就提前创建backup.gz空文件,哪怕mongodump没有输出任何有效备份数据,这个空文件也会保留在磁盘上。
解决方法
方法1:使用PIPESTATUS数组获取管道内各命令的退出码
Bash 内置的PIPESTATUS数组存储了最近一次管道链中所有命令的退出码,下标从0开始,${PIPESTATUS[0]}对应第一个命令mongodump的退出码,${PIPESTATUS[1]}对应第二个命令gzip的退出码。注意该数组会被后续执行的任何命令覆盖,需要在管道执行完成后立刻读取:
for i in $(seq 1 30); do mongodump --host mongodb -u user -p password --archive | gzip > backup.gz mongodump_exit=${PIPESTATUS[0]} echo "mongodump exit code: $mongodump_exit" if [ "$mongodump_exit" -eq "0" ]; then break fi # 清理无效备份文件,避免后续误用 rm -f backup.gz # 增加重试间隔,减轻数据库压力 sleep 2 done if [ "$mongodump_exit" -eq "0" ]; then echo "do something with the file" fi
方法2:拆分备份与压缩步骤(逻辑更直观)
如果不想处理管道退出码的问题,可以先让mongodump直接输出未压缩的归档文件,确认备份成功后再单独执行压缩操作:
for i in $(seq 1 30); do mongodump --host mongodb -u user -p password --archive=backup.tmp check=$? echo "mongodump exit code: $check" if [ "$check" -eq "0" ]; then gzip backup.tmp mv backup.tmp.gz backup.gz break fi rm -f backup.tmp sleep 2 done if [ "$check" -eq "0" ]; then echo "do something with the file" fi
额外校验建议
可以在备份完成后增加模拟恢复步骤,进一步确认备份文件的有效性,避免出现备份流程返回成功但实际文件损坏的情况:
# 仅模拟恢复,不会写入实际数据 mongorestore --archive=backup.gz --gzip --dryRun if [ $? -ne 0 ]; then echo "备份文件损坏,执行后续失败逻辑" exit 1 fi
内容的提问来源于stack exchange,提问作者praiseHellRaiseDale
相关产品推荐
相关产品推荐

