用同一组样本完成计划、复制和恢复
这次任务是把一个静止的个人目录复制到新的目标目录,证明内容可读,并留下容量和传输结果。准备一个可写工作目录、足够的目标空间,以及已经安装且能查询版本的传输工具。练习只创建两份小文本,其中一个是隐藏文件,不使用真实照片库或运行数据。下面建立独立实验根目录并进入它,之后所有相对路径都以这里为起点。若换成真实个人资料,先让源停止变化,并重新列出需要保护的范围。
先确认源目录和目标所在文件系统。目标如果是外接盘或已挂载共享,必须检查它当前确实挂载到计划位置;一个同名本地目录不能代替失去连接的外部存储。容量预算不只看源目录占用,还要考虑目标现有副本、传输临时文件与文件系统行为。源文件分配空间和逻辑大小可能不同,压缩、稀疏文件和硬链接都会影响估计,所以前文的目录统计只能提供预算依据,不是实际所需容量的精确承诺。
把目标设为独立新目录后,再对这个确切目录做预演。前文的通用预演展示尾斜杠含义;完整案例必须在真正复制前使用同一个已创建目标,不能预演一个路径却复制到另一个路径。记录工具版本是因为 Mac 自带版本、GNU/Linux 安装版本和 DSM 厂商版本可能不同,归档选项对元数据的支持也随编译能力与目标文件系统变化。不要从命令名字相同推断两端功能相同。
transfer_lab=$(mktemp -d ./transfer-lab.XXXXXX) && cd "$transfer_lab" && mkdir personal-lab && printf 'personal sample\n' > personal-lab/sample.txt && printf 'hidden sample\n' > personal-lab/.markerwrite:只写新实验目录;真实源场景省略这一步。
rsync --versionread:确认选项与能力;不连接远端。
先查写入路径所在的文件系统
构建报空间不足时,先确定实际写入位置:源代码所在盘、临时目录、容器可写层和挂载卷可能完全不同。查询某个确定路径比查看整机磁盘列表更容易解释。如果 NAS 或外接盘没有挂载,同名目录可能落在本机系统盘上,后续备份就会写错地方。确认路径对应预期文件系统与挂载位置后,才讨论剩余空间。
df 反映文件系统视角,不是某个目录占用。显示还有可用容量时,也可能受到用户配额、保留空间或其他限制。不要依据单个百分比自动删除资料;先保留报错文字、路径和采样时间。网络文件系统查询可能等待服务端,read 也不是零负担。本篇所有路径均为个人实验示例,没有连接 NAS 或执行实际传输。
df -hT -- ./personal-lab-h 易读容量,-T 显示文件系统类型;明确路径以避免误看另一块盘。 示意:Use% 82%、Avail 20G;是文件系统视角,不是目录大小。 不存在先核对挂载;容量还有配额、保留空间等限制。远程挂载可能阻塞,不能由百分比直接决定删除。
小文件过多时,容量数字可能误导
传统固定 inode 的文件系统可能在数据块尚有余量时用完 inode,表现为无法创建新文件。依赖缓存、小尺寸日志与重复构建输出容易积累大量目录项。用 inode 视角与容量视角交叉比较,可以判断是否进入这条分支;但不同文件系统管理 inode 的方式不同,动态分配或特殊报告值不能直接套用固定比例的结论。
确认是小文件问题后,先找出拥有者与生成机制:是正常缓存可由工具管理,还是程序不断产生意外文件。清理仍应通过对应应用支持的流程,并先确认有没有独有数据。不要把找到的小文件全部删除,也不要动容器存储驱动目录或 DSM 隐藏目录。只释放空间却不解决增长原因,往往会让故障在下一次构建或备份时重现。
df -i -- ./personal-lab-i 切换为 inode 使用统计,适合大量小文件导致创建失败的场景。 示意:IUse% 100% 而容量仍空闲,提示 inode 可能耗尽。 部分文件系统动态分配 inode 或显示特殊值,不能照搬 ext4 结论;确认文件系统类型与实际报错。
du 与 df 不一致时先解释口径
du 逐项遍历目录并估计分配空间,适合从个人目录逐层定位;显示深度受限不代表只访问浅层,计算汇总仍需遍历下层文件。目录很大时会带来明显 I/O,应该在负载较低时限定范围。权限拒绝会使结果不完整,硬链接去重、稀疏文件和写时复制共享也会影响直觉中的大小。不要将不同单位、不同范围的数字直接相减。
df 与 du 的差异还可能来自快照、元数据、仍被进程打开的已删除文件以及挂载覆盖等。发现差异只是线索,不应立刻重启或清空日志。先核对两者是否看同一文件系统,再结合应用或平台的容量界面排查。DSM 的快照和套件数据应使用受支持管理界面核对,不要照搬 GNU du 长参数扫描整个系统卷。
du -x -h --max-depth=1 -- ./personal-lab-x 限制同一文件系统,-h 易读单位,--max-depth=1 只显示到第一层的汇总;遍历仍会读更深层目录。 示意:6.0G ./personal-lab/cache;是分配空间估算,硬链接默认避免重复统计。 权限拒绝会低估;大量目录会产生 I/O。macOS 不支持此 GNU 长选项;不要扫描 DSM 系统根目录。
rsync 尾斜杠决定目标层级
源路径 personal-lab/ 的尾斜杠表示复制其中内容;源路径 personal-lab 不带尾斜杠,在目标目录已存在的常见场景下会把目录自身放入目标中。目标是否存在也可能影响单项复制的命名,所以每次传输都应明确目标是目录,并先预演。不要把源和目标顺序靠记忆填写;从数据流向读一遍,再看逐项输出中的相对路径是否符合预期。
dry-run 的 -n 让本次 rsync 不实际传输,适合发现路径和范围错误,但它不是已经成功的备份,也不能保证随后源文件不变化。预演仍要扫描文件,远程模式还会连接服务器并产生记录。无输出通常只代表按当前比较规则无需更新;默认快速比较不是全量内容证明,更不能检验权限、应用状态和未来恢复能力。
rsync -anvi -- ./personal-lab/ ./backup-preview/-a 归档模式、-n 不实际传输、-v 明细、-i 逐项变化;源尾斜杠表示复制内容,目标也以目录形式明确。 示意:>f+++++++++ notes.txt 表示计划新增文件;不是已经备份成功。 路径写反会反转意图;无输出未必全面一致。-a 不包含 ACL、扩展属性和硬链接的全部保留,需要另核验。
真正复制前保证目标可辨认且可回退
最容易审查的初次复制方式,是向唯一的新目录写入,保留旧副本。示例通过 mktemp 创建目标,只有创建成功才继续。归档模式保留常见元数据,但并不自动包含所有 ACL、扩展属性和硬链接语义;跨到 SMB、外接文件系统或 Mac 时尤其需要按用途验收。个人照片只看内容可能足够,应用配置与可执行文件还需要权限信息。
本文默认不使用 --delete:目标中多出的文件不会因源缺失而删除,避免把路径错误放大成清空事故。但不删除也意味着目标不一定是完全镜像,验收时要明确这一点。复制若覆盖目标同名文件,即使没有删除参数也应按 danger 处理;本例写入唯一新目录时按 write 处理。遇到空间不足、权限失败或部分传输错误时,保留错误记录并核对未完成项,不只看最后几行进度。
本节的归档模式命令是保留基本元数据的可选方案。下面完整小文本案例采用递归与时间保留,二者择一;不要先执行本节复制又把已经写入的目标当成下一节的新空目录。
backup_dir=$(mktemp -d ./backup.XXXXXX) && rsync -avi -- ./personal-lab/ "$backup_dir/"创建唯一的新目标目录再复制,-a 尽力保留基本元数据,-v/-i 显示变化;先执行对应 dry-run 并确认源目录。 示意:出现文件清单,退出 0 表示本次 rsync 完成;还需内容与恢复验收。 空间不足或部分文件传输失败时保留目标待检查;没有 --delete。不同文件系统可能无法保留属主或权限。
预演通过以后才执行同一目标的复制
先创建一个新目标,把返回路径写入本次记录,然后运行预演。逐项结果应该显示样本文件将新增到目标根目录,而不是额外嵌入一层源目录;隐藏标记也应包含。若看到不相关目录或大量意外变化,停止在预演阶段,检查源目标顺序和当前目录。预演不传输数据,但会遍历目录和读取元数据;远程预演还会连接目标,所以它不是完全不产生负载的纸面计算。
确认范围后移除预演选项,保留相同源、相同目标与尾斜杠。下面完整案例用递归与时间保留作为个人内容副本的最小选择,避免让普通用户为无法保留他人所有权而失败。若任务确实需要归档模式的基本权限和属主语义,可采用前文归档方案,但仍要把访问控制列表、扩展属性和硬链接作为单独需求审查。不要为了让终端退出成功,静默放弃任务本来要求保留的元数据。
传输退出后立即保存退出码。若其中一部分文件失败,目标可以保留用于诊断,但不能当成完整副本。返回成功后进入内容比较,不以进度百分比作为验收。案例不删除目标多余文件,也不覆盖旧备份,因为初始目标独立且为空;如果中断后向同一目标重试,就可能覆盖前次同名文件,按 danger 分类,并在重试前再次预演。不要把追加镜像删除选项当成让结果干净的默认手段。
backup_dir=$(mktemp -d ./backup.XXXXXX) && rsync -rtni -- ./personal-lab/ "$backup_dir/"write:创建目标目录;rsync 部分为 dry-run。成功后保留变量并审查逐项输出。
rsync -rti -- ./personal-lab/ "${backup_dir:?create and review destination first}/"
copy_status=$?
printf 'rsync_exit=%s\n' "$copy_status"write:要求目标仍为刚创建空目录;若已有同名文件则可能覆盖,应先重新核对并按 danger 处理。
传输完成之后还有恢复验收
摘要比较能帮助验证选定文件的字节一致,但不检查目录遗漏、属主、权限、文件扩展属性或应用能否读取。先选固定不变化的个人样本,分别计算源与恢复副本摘要,再用原应用打开。若样本还在被写入,两次读取不同内容并不自动说明传输损坏;应先取得一致性输入。对在线数据库,普通目录复制不能代替应用支持的备份流程。
留下一份简短记录:源范围、目标实际路径、复制时间、退出状态、样本摘要比较结果以及没有验证的内容。rsync 不是历史版本管理器,下一次同步不会天然保留被覆盖前的内容;需要版本保留时使用独立备份方案。只有把恢复后的数据真正用起来,才完成本轮验收;旧副本的清理应作为另一个经过核对的步骤。
sha256sum -- ./personal-lab/sample.txt "${backup_dir:?complete copy first}/sample.txt"分别计算两个文件内容摘要,人工比较前面的 64 位十六进制值;文件名不同不影响摘要。 示意:两行摘要相同才支持这两个文件字节内容一致;本文不提供虚构校验值。 读取失败不能跳过;摘要不比较权限、ACL 或来源可信度。文件持续变化时应先冻结测试样本。
用双向内容检查补足复制完成的证据
默认快速比较主要依赖文件大小和修改时间,不能作为完整字节一致的证明。对于本例的小型静止目录,复制完成后使用内容校验预演,读取源和目标所选文件。输出为空且退出成功说明按当前范围无需更新;如果目标一开始并非空目录,没有删除选项的正向比较不会报告目标多出的文件。因此本例补一次反向只读预演,用于观察目标是否含有源没有的项,不执行任何反向复制。
双向比较也不等于验证所有元数据,它回答的是本例选中的递归内容范围。再对样本文本计算摘要,人工比较两行值,并打开恢复副本确认能读。隐藏标记要加入检查,因为只看可见文件容易漏掉配置类材料。若校验阶段出现差异,先判断源是否仍在变化、是否使用了同一目标、传输是否报告部分失败,再考虑存储或读取问题;不能仅凭一次差异就断言介质损坏。
要验证能从副本重新获得数据,可以把备份目录中的样本复制到另一个新恢复目录,再比较源样本与恢复样本。不要在原目录上进行首次恢复,也不要把测试恢复当成删除原件的前置许可证。真正的恢复演练应以使用需求验收:文本能读取、照片能打开、程序配置能被合适版本应用识别。本文只提供小文本案例,因此不声称覆盖数据库一致性、照片库结构或完整系统迁移。
rsync -rnci -- ./personal-lab/ "${backup_dir:?}/"
rsync -rnci -- "$backup_dir/" ./personal-lab/read:两条均含 -n;第二条只观察目标多余项及差异,不实际反向复制。
sha256sum -- ./personal-lab/sample.txt "${backup_dir:?}/sample.txt"read:GNU/Linux 的 GNU sha256sum;macOS 用 shasum -a 256 对同一对路径比较。
restore_dir=$(mktemp -d ./restore.XXXXXX) && rsync -rt -- "${backup_dir:?}/sample.txt" "$restore_dir/"write:新恢复目录,不覆盖原件。
cmp ./personal-lab/sample.txt "${restore_dir:?}/sample.txt"read:无输出且退出 0 支持字节一致;读取失败与内容不同要分开处理。
空间故障与传输故障要分别处理
有空闲容量却不能创建文件时,结合文件系统类型查询索引节点使用情况;大量小文件可能先耗尽可用节点。若节点统计不适用于当前文件系统,就回到实际错误和存储界面,而不是套用某种文件系统的固定结论。目录占用与文件系统已用空间差异很大时,考虑统计范围、权限遗漏、快照或已删除但仍被进程占用的文件等可能;这些是待验证分支,不是看到差值就可以删除日志的依据。
传输提示空间不足时,保留原件和未完成目标,重新核对真正写入的文件系统,不立即删掉旧副本来腾空间。提示权限不足时,分辨是无法读取源,还是无法创建目标或保留某项元数据,再按任务需求处理。提示源文件在遍历后消失时,可能是源仍在变化;如果任务要求固定时点副本,应重新取得稳定输入,而不是忽略这种状态。工具退出码需要结合具体错误说明解释,任何非零结果都要在本次记录里有对应处理。
收尾记录源范围、目标真实路径、挂载位置、工具版本、预演结论、实际复制退出码、双向比较与恢复样本结果。还要注明采用的是内容副本还是需要元数据的归档副本,是否保留历史版本,以及哪些类型没有验证。同步工具本身不会替你保留每次被覆盖前的历史内容;有长期版本需求时,把这次合格副本纳入明确的备份保留方案。清理实验目录作为另一步按实际路径核对,本文不附批量删除命令,也不在完成复制后自动删除源。
容量预算示意可以算清楚再决定是否开工:假设稳定源逻辑大小十二吉字节,目标可用二十吉字节,计划新增一份完整副本十二吉字节,并留三吉字节给临时开销和操作余量,则预算剩余五吉字节。这不是通用余量比例,也不是工具保证,稀疏文件、元数据和目标配额都可能改变实际需求;如果目标可用只有十四吉字节,就不足以满足这张预算,先调整目的地或保留计划,不在复制中途赌空间够用。
项目 示例预算 GiB
目标可用 20
新增完整副本 12
临时开销及操作余量 3
预算剩余 5 = 20 - 12 - 3
真实执行前用实际容量重算;本表未实机测量阅读用示意材料;不是命令输出或实测记录,复制保存为记录文件属于 write。