4. 镜像文件操作:dd命令创建与备份镜像、参数详解、压缩与挂载

镜像文件操作,说白了就是给磁盘或分区做“快照”。你想想看,生产环境里一个系统跑了大半年,配置、数据、依赖库全都调顺了,万一硬盘挂了怎么办?这时候,一个完整的镜像文件就是你的救命稻草。

我个人习惯把镜像操作分成三个环节:创建与备份、压缩与解压、挂载与验证。下面咱们一个一个来过。

4.1 dd命令:镜像创建与备份的瑞士军刀

dd 这工具,名字很朴素,功能却极其强大。它的核心逻辑就是“从哪读,往哪写,读多少,怎么写”。

核心语法:

dd if=<输入文件> of=<输出文件> [bs=<块大小>] [count=<块数>] [seek=<跳过块数>]

我在项目中遇到过好几次,新手直接用默认参数备份一块 1TB 的硬盘,结果等了半天没反应。为什么?因为默认的 bs 只有 512 字节,拷贝大文件时效率极低。

4.1.1 参数详解:bs、count、seek

参数 含义 典型值 我的建议
bs 块大小,每次读写的数据量 1M, 4M, 64K 磁盘备份用 1M,网络传输用 64K
count 读取的块数,与 bs 配合决定总数据量 1024, 4096 做小范围快照时必用
seek 写入时跳过输出文件开头的块数 0, 2048 恢复镜像到分区中间位置时很实用

实战示例:

# 备份整个 /dev/sda 到镜像文件(bs=1M,效率高)
dd if=/dev/sda of=/backup/sda.img bs=1M status=progress

# 只备份前 2GB 数据(count=2048,bs=1M)
dd if=/dev/sda of=/backup/sda_boot.img bs=1M count=2048

# 恢复镜像到 /dev/sdb,跳过前 1GB(seek=1024)
dd if=/backup/sda.img of=/dev/sdb bs=1M seek=1024

小技巧: 加上 status=progress 参数,dd 会实时显示拷贝进度和速度。我每次做大规模备份都会加这个,心里踏实。

4.2 镜像压缩与解压:gzip 与 xz

原始镜像文件有多大?一块 500GB 的硬盘,dd 出来的镜像就是 500GB。直接存太浪费空间了。所以,压缩是必须的。

我常用的两种压缩工具:gzip 和 xz。它们各有千秋。

工具 压缩比 速度 适用场景
gzip 中等(约 2-4 倍) 快 日常备份、快速归档
xz 高(约 4-8 倍) 慢(压缩耗时) 长期归档、节省存储空间

实战示例:

# 创建并压缩镜像(gzip)
dd if=/dev/sda bs=1M | gzip > /backup/sda.img.gz

# 解压并恢复镜像(gzip)
gunzip -c /backup/sda.img.gz | dd of=/dev/sda bs=1M

# 创建并压缩镜像(xz,压缩比更高)
dd if=/dev/sda bs=1M | xz -z > /backup/sda.img.xz

# 解压并恢复镜像(xz)
xz -dc /backup/sda.img.xz | dd of=/dev/sda bs=1M

注意: 压缩后的镜像不能直接挂载。必须先解压成原始镜像文件,或者用 losetup 配合偏移量处理。我曾经因为直接挂载 .gz 文件折腾了半天,后来才发现问题。

4.3 镜像挂载:losetup 与 mount -o loop

镜像文件创建好了,怎么查看里面的内容?直接挂载!

Linux 提供了两种方式:losetup 和 mount -o loop。前者更底层,后者更便捷。

4.3.1 使用 mount -o loop(简单场景)

如果你的镜像文件是单个分区(比如一个 ext4 文件系统),直接用 mount -o loop 就行。

# 挂载镜像文件到 /mnt
mount -o loop /backup/sda1.img /mnt

# 查看内容
ls /mnt

# 卸载
umount /mnt

嗯,这里要注意:mount -o loop 会自动帮你找空闲的 loop 设备,省心。但如果是整个磁盘的镜像(包含分区表),就不能这么用了。

4.3.2 使用 losetup(复杂场景)

整个磁盘的镜像,需要先用 losetup 关联到 loop 设备,再用 kpartx 或 partprobe 扫描分区表。

# 关联镜像到 loop0
losetup /dev/loop0 /backup/sda.img

# 扫描分区表
partprobe /dev/loop0

# 查看分区
ls /dev/loop0p*

# 挂载第一个分区
mount /dev/loop0p1 /mnt

# 卸载并释放
umount /mnt
losetup -d /dev/loop0

我的习惯: 用 losetup -P 自动扫描分区表,省去手动 partprobe 的步骤。比如 losetup -P /dev/loop0 /backup/sda.img,分区设备会直接出现。

4.4 知识体系总览

下面这张图,把镜像文件操作的整个流程串起来了。从创建到挂载,每一步都有对应的工具和参数。

镜像文件操作知识体系 镜像文件操作知识体系 镜像文件 创建与备份 (dd) 压缩与解压 挂载与验证 bs 参数 count 参数 seek 参数 gzip xz 解压恢复 mount -o loop losetup kpartx 核心原则 创建时选对 bs 和 count,压缩时权衡速度与空间,挂载时区分单分区与整盘镜像 每一步都验证,避免“备份一时爽,恢复火葬场”

4.5 避坑指南

最后,分享几个我踩过的坑,希望能帮你少走弯路。

  • dd 方向搞反: 我曾经把 if 和 of 写反了,结果把空文件写回了源盘,数据全丢了。所以,每次执行 dd 前,我都会默念三遍“if 是源,of 是目标”。
  • 压缩后直接挂载: 前面提过,压缩镜像不能直接挂载。必须先解压,或者用 losetup 配合偏移量处理。
  • 挂载整盘镜像时忘记扫描分区表: 用 losetup 关联后,一定要用 partprobe 或 kpartx 扫描分区表,否则看不到分区设备。
  • 磁盘空间不足: 创建镜像前,先检查目标目录的剩余空间。用 df -h 看一眼,别等到 dd 报错才后悔。

重要提醒: 镜像操作涉及数据安全,建议先在测试环境练手。尤其是 dd 和 losetup,一旦操作失误,数据恢复成本极高。