3. tar与cpio实战
在RHEL的备份恢复体系中,tar与cpio是最基础也最可靠的两个归档工具。它们不依赖守护进程,不需要数据库,仅凭文件系统本身就能完成打包、压缩、校验与还原。理解它们的选项语义,尤其是权限、SELinux上下文和增量归档的处理方式,是构建可恢复备份的关键。
一、归档与压缩:先打包,再压缩
归档(archive)与压缩(compress)是两个独立动作。tar负责把多个文件与目录串成一个连续的流,压缩则由gzip、bzip2、xz等工具完成。RHEL 9默认提供gzip与xz,bzip2需额外安装。常见组合如下:
# 仅归档,不压缩
tar -cvf /backup/etc.tar /etc
# gzip压缩,扩展名.tar.gz
tar -czvf /backup/etc.tar.gz /etc
# xz压缩,压缩率更高但更慢
tar -cJvf /backup/etc.tar.xz /etc
# 查看归档内容,不解包
tar -tzvf /backup/etc.tar.gz
选项含义需要记牢:-c创建、-x解包、-t列出、-v显示过程、-f指定文件名。-z对应gzip,-j对应bzip2,-J对应xz。压缩格式由扩展名约定,但tar并不强制校验扩展名,恢复时必须显式给出对应选项,否则会报“not in gzip format”。
cpio的工作方式不同,它从标准输入读取文件列表,因此常与find配合:
find /etc -print | cpio -ov > /backup/etc.cpio
find /etc -print | cpio -ov -H newc | gzip > /backup/etc.cpio.gz
cpio -itv < /backup/etc.cpio
cpio的优势在于能精确控制文件列表,适合配合find的-newer、-mtime做条件归档;tar则更适合整目录打包。两者都能保留权限与时间戳,但默认行为有差异,下面重点说明。
二、保留权限、属主与SELinux上下文
归档时若不保留元数据,恢复后文件可能无法被服务读取。tar默认以当前用户身份归档,解包时默认按当前用户还原属主,只有root才能完整还原属主与属组。关键选项是-p(保留权限)与--same-owner:
# root执行,保留权限与属主
tar -czpvf /backup/etc.tar.gz /etc
# 解包时保留权限,并以归档中的属主还原
tar -xzpvf /backup/etc.tar.gz -C /
SELinux上下文是RHEL特有的关键元数据。tar在较新版本中支持--selinux,可在归档中保存security.selinux扩展属性;解包时若目标系统启用了SELinux,需确保上下文正确,否则httpd、sshd等服务会因标签错误被拒绝访问。实践中更稳妥的做法是:归档时加--selinux,恢复后对关键目录执行restorecon -Rv,让策略根据路径重新计算上下文。
tar --selinux -czpvf /backup/etc-selinux.tar.gz /etc
tar --selinux -xzpvf /backup/etc-selinux.tar.gz -C /
restorecon -Rv /etc/httpd /etc/ssh
cpio对应选项为--selinux(归档)与--selinux(解包),同样建议恢复后执行restorecon。需要注意:如果备份介质是FAT或NFS且未启用xattr,SELinux上下文可能丢失,此时restorecon是唯一可靠的补救手段。
三、增量归档:GNU tar的--listed-incremental
GNU tar提供--listed-incremental实现增量归档。它维护一个快照文件(snapshot),记录上次归档时各目录的mtime与inode状态。下次归档时,tar对比快照,只打包发生变化的文件。级别0为全量,级别1为基于上次快照的增量。
# 首次全量,生成快照
tar --listed-incremental=/backup/etc.snar -czpvf /backup/etc-0.tar.gz /etc
# 后续增量,复用同一快照
tar --listed-incremental=/backup/etc.snar -czpvf /backup/etc-1.tar.gz /etc
恢复时必须按顺序解包:先全量,再逐级增量,且每次都要带--listed-incremental指向快照或使用--incremental。顺序错误会导致文件被旧版本覆盖。cpio没有内建增量机制,通常用find的-newer配合时间戳文件实现:
touch /backup/etc.stamp
find /etc -newer /backup/etc.stamp -print | cpio -ov > /backup/etc-inc.cpio
touch /backup/etc.stamp
四、从归档中恢复单个文件与目录
恢复单个文件是tar最实用的能力之一。先用-t确认路径,再用-x加具体路径解包。注意路径必须与归档内记录一致,通常以/开头或去掉前导斜杠,取决于打包方式。
# 列出归档中与sshd相关的条目
tar -tzf /backup/etc.tar.gz | grep sshd
# 只恢复sshd_config
tar -xzf /backup/etc.tar.gz -C / etc/ssh/sshd_config
# 恢复整个目录
tar -xzf /backup/etc.tar.gz -C / etc/ssh
cpio恢复单个文件需借助-i与模式匹配:
cpio -idv "etc/ssh/sshd_config" < /backup/etc.cpio
恢复后应检查三件事:文件权限是否为预期值、属主属组是否正确、SELinux上下文是否匹配。可用ls -lZ查看,若上下文异常,执行restorecon -v 文件路径。对于配置文件,恢复后建议用sshd -t或httpd -t做语法校验,确认服务可正常加载。
五、实战建议与常见陷阱
第一,归档前先确认目标路径。tar打包时若使用绝对路径,解包会覆盖原位置;若使用相对路径,解包位置由-C决定。建议统一用-C /加相对路径,避免误覆盖。
第二,压缩格式与恢复选项必须匹配。用-J创建的xz归档,恢复时也要用-J;用gzip创建的,恢复用-z。若不确定,先用file命令识别:
file /backup/etc.tar.gz
# 输出:gzip compressed data
第三,增量归档的快照文件必须与归档文件一同保存。丢失snar文件后,下一次增量会退化为全量,且无法正确判断变化范围。建议把snar与对应归档放在同一目录,并在命名上体现级别与日期。
第四,恢复单个文件时,若归档内路径带前导斜杠,解包命令中的路径也要带;若不带,则去掉。可用tar -tzf先确认。cpio恢复时模式匹配区分大小写,建议先用cpio -it列出确认。
--selinux与--xattrs。若需跨系统恢复,建议同时加--acls --xattrs --selinux,确保ACL、扩展属性与SELinux标签完整保留。tar -xzf直接解包到/而不加-C,也不要在未确认归档内容的情况下覆盖生产配置。恢复前先tar -tzf列出,或先解包到临时目录比对,再决定是否覆盖。掌握以上要点后,tar与cpio足以应对RHEL中绝大多数文件级备份与恢复场景。关键在于:归档时保留元数据,恢复时按序解包,恢复后核对权限、上下文与服务状态,形成可验证的闭环。