服务公告

服务公告 > 综合新闻 > Backup:备份故障排查

Backup:备份故障排查

发布时间:2026-04-23 12:00

一、前言

搞过的人都知道,最烦的是备份任务半夜挂了,早上起来才发现数据没存住。Backup:备份故障排查这课专门讲清楚:备份脚本跑不动、rsync卡死、tar报权限错误、磁盘满导致任务中断这类破事怎么快速定位。别废话,直接上排障思路和命令。

二、操作步骤

步骤1:确认备份任务实际运行状态

# 检查cron任务是否存在(CentOS/RHEL)
crontab -l | grep -i backup

# 检查cron任务是否存在(Ubuntu/Debian)
cat /var/spool/cron/crontabs/root 2>/dev/null || cat /etc/crontab
# 示例输出
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
# 任务存在,下一步检查脚本本身

步骤2:查看备份日志最近的错误信息

tail -100 /var/log/backup.log | grep -E "(error|failed|cannot|denied)" -i
# 示例输出
tar: /data/prod: Cannot open: Permission denied
tar: Error is not recoverable: exiting now
# 权限问题,文件属主和运行用户不匹配

步骤3:确认备份脚本执行用户的文件权限

# 查看脚本属主和权限
ls -la /opt/scripts/backup.sh

# 查看备份源目录权限
ls -ld /data/prod

# 确认cron运行用户
ps aux | grep crond | grep -v grep

# 示例输出
-rwxr-xr-x  1 root root  16384 Dec 20 02:00 /opt/scripts/backup.sh
drwxr-xr-x  2 root root  65536 Dec 20 10:30 /data/prod
# root才能读,脚本是root属主但cron用什么用户跑?

步骤4:检查目标磁盘空间是否足够

# CentOS/RHEL 路径
df -h /backup

# Ubuntu 路径(可能是/var/backup或其他)
df -h /var/backups

# 示例输出
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       500G  485G   15G  97% /backup
# 97%满了!备份写到一半会炸

步骤5:测试备份命令本身是否正常(隔离问题)

# 用同样参数手动跑一次,看具体报错
cd /data && tar -czf /backup/test-manual.tar.gz ./prod 2>&1

# 示例输出
tar: ./prod/file-2023.log: File changed while being read
tar: ./prod/db.sqlite: Cannot stat: No such file or directory
# 文件被其他进程占用或者刚被删了

步骤6:排查网络备份(rsync/scp)的连通性

# 测试网络路径可达性
ping -c 3 192.168.1.100
ssh -o ConnectTimeout=5 backup-user@192.168.1.100 "df -h /backup"

# 测试rsync模块列表
rsync backup-user@192.168.1.100::

# 示例输出
PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data.
64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=0.3 ms
# 网络通,检查ssh key和rsync配置

步骤7:验证备份文件完整性(最重要的一步)

# 检查tar包完整性
tar -tzf /backup/daily-backup-20231220.tar.gz > /dev/null 2>&1 && echo "OK" || echo "CORRUPTED"

# 检查rsync快照一致性
rsync -avnc --stats /backup/snapshot/ /mnt/restore-test/

# 示例输出
tar: This does not look like a tar archive
CORRUPTED
# 备份文件损坏,需要重新备份或者从上一个完整备份恢复

三、常见问题FAQ

Q1:备份日志显示"Read-only file system"错误怎么破?

这说明你备份目标路径挂载的盘变只读了。常见原因:磁盘故障、文件系统损坏、挂载参数写成了ro。
先执行 mount | grep /backup 看挂载参数,然后执行 dmesg | tail -50 查内核日志有没有磁盘I/O错误。
如果是NFS/ CIFS共享,先确认服务端允许写入。实在不行,赶紧换一台健康的机器做备份目标,别硬撑。

Q2:rsync备份到远程服务器,每次都重新传输全部文件,什么鬼?

先排除三个常见原因:①源目录的修改时间被改了(touch -r命令同步时间),②rsync目标端权限不对导致增量失效,③SSH密钥有密码导致每次认证行为异常。
强制增量测试:rsync -avz --dry-run /source/ user@remote:/dest/ 看要不要传。
如果加了 --delete 参数,删掉目标文件也会导致全量重传。检查备份脚本里有没有加错参数。

Q3:备份脚本在cron里跑没问题,但手动执行报错,是环境变量问题吗?

对,cron和终端环境差了十万八千里。cron默认PATH极短,脚本里用的 pg_dumpmysql 这类命令找不到路径。
解决方案:在脚本开头加 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,或者用绝对路径调用命令。
另一个坑:cron没有TTY,某些需要交互确认的命令会直接挂掉,比如 ssh-copy-id 或者需要输入密码的scp。

Q4:备份磁盘空间清理不掉,du显示的和df对不上?

通常是删了文件但进程还在占用(deleted状态)。执行:
lsof +D /backup 2>/dev/null | grep deleted
找到还在写那个文件的进程,重启或kill掉,空间才能真正释放。
另一个原因:硬链接或者snapshot占用。比如LVM snapshot没删干净,或者rsnapshot配置了过多保留版本。

四、总结

核心要点:

  • 备份故障排查优先级:先确认任务是否实际跑了,再查日志定位错误类型,最后隔离测试单条命令
  • 权限问题是本地备份TOP1原因,NFS/CIFS共享先确认服务端权限模型
  • 磁盘空间永远要留20%以上余量,别等写满了才想起来扩
  • 备份完了必须校验完整性,tar -tzf 能过才算成功,别把损坏包当宝贝
  • 网络备份优先用rsync并配置SSH免密,定期测一次网络中断恢复

延伸阅读:

  • BorgBackup — 专注重复数据删除的备份工具,适合大量小文件场景
  • Restic — 支持加密、去重、多种后端(本地、S3、Azure Blob)
  • BackupPC — 企业级LAN备份方案,跨平台支持好
  • 《The DevOps Handbook》第九章 — 备份恢复策略设计