rsync增量备份脚本备份目录大小翻倍,如何修复?
问题修复方案
你的脚本未实现增量备份的核心原因有两个:路径处理逻辑错误,以及未妥善处理首次备份时--link-dest指向无效路径的情况。以下是具体修复步骤:
1. 修复路径处理逻辑
原脚本强制给参数添加根路径前缀/,会导致相对路径被错误转为根目录下的绝对路径,不仅可能偏离你实际要备份的目录,还会破坏rsync硬链接的路径匹配逻辑。
将脚本中SOURCE_DIR和BACKUP_DIR的定义修改为:
readonly SOURCE_DIR="$(realpath "$1")" readonly BACKUP_DIR="$(realpath "$2")/$(basename "$1")"
realpath会把任意路径转为绝对路径,避免相对路径带来的混乱;- 用
basename "$1"提取源目录的最后一级名称,让备份目录结构更简洁(比如备份/home/user/docs到/backup,会生成/backup/docs目录,而非/backup/home/user/docs)。
2. 处理首次备份的--link-dest参数
首次运行脚本时,latest软链接不存在,rsync会忽略无效的--link-dest参数直接执行全量备份,但显式判断链接状态能避免潜在的路径解析问题。
在mkdir -p "${BACKUP_DIR}"之后添加:
# 处理首次备份时--link-dest不存在的情况 RSYNC_LINK_DEST="" if [ -L "${LATEST_LINK}" ]; then RSYNC_LINK_DEST="--link-dest=${LATEST_LINK}" fi
然后修改rsync命令,动态传入--link-dest参数:
rsync -av --delete \ "${SOURCE_DIR}/" \ ${RSYNC_LINK_DEST} \ --exclude=".cache" \ "${BACKUP_PATH}"
3. 完整修复后的脚本
#!/bin/zsh # 增量备份脚本(基于rsync硬链接实现) set -o errexit set -o nounset set -o pipefail incremental_bckp_rsync_dir(){ readonly SOURCE_DIR="$(realpath "$1")" readonly BACKUP_DIR="$(realpath "$2")/$(basename "$1")" readonly DATETIME="$(date '+%Y-%m-%d_%H:%M:%S')" readonly BACKUP_PATH="${BACKUP_DIR}/${DATETIME}" readonly LATEST_LINK="${BACKUP_DIR}/latest" mkdir -p "${BACKUP_DIR}" # 处理首次备份时--link-dest不存在的情况 RSYNC_LINK_DEST="" if [ -L "${LATEST_LINK}" ]; then RSYNC_LINK_DEST="--link-dest=${LATEST_LINK}" fi rsync -av --delete \ "${SOURCE_DIR}/" \ ${RSYNC_LINK_DEST} \ --exclude=".cache" \ "${BACKUP_PATH}" rm -rf "${LATEST_LINK}" ln -s "${BACKUP_PATH}" "${LATEST_LINK}" } # 调用示例:传入源目录和备份根目录(支持相对/绝对路径) incremental_bckp_rsync_dir path/to/dir path/to/backup
验证增量效果
修复后再次运行脚本,用du -h --apparent-size path/to/backup查看表观大小(会显示所有文件的总大小,包括硬链接),用du -h path/to/backup查看实际占用磁盘空间(会合并硬链接的大小,仅统计一次)。如果实际占用空间远小于表观大小,说明增量备份已生效。
内容的提问来源于stack exchange,提问作者ecjb
相关产品推荐
相关产品推荐

