lio*_*ori 5 linux filesystems backup snapshot
我想以编程方式在Linux中制作实时文件系统的快照,最好使用LVM.我不想卸载它,因为我已经打开了很多文件(我最常见的情况是我有一个繁忙的桌面有很多程序).
我理解,由于内核缓冲区和一般文件系统活动,磁盘上的数据可能处于某种或多或少的未定义状态.
有没有办法"原子地"卸载FS,制作LVM快照并将其挂载?如果操作系统将阻止所有活动几秒钟来执行此任务,那就没问题.或者也许某种原子"同步+快照"?内核通话?
我不知道是否有可能......
有什么方法可以“自动”卸载 FS、制作 LVM 快照并将其重新安装吗?
即使文件系统不在 LVM 卷上,也可以对已安装的文件系统进行快照。如果文件系统位于 LVM 上,或者它具有内置快照设施(例如 btrfs 或 ZFS),则改用它们。
以下说明相当低级,但如果您希望能够对不在 LVM 卷上的文件系统进行快照,并且无法将其移动到新的 LVM 卷,那么它们可能会很有用。尽管如此,它们并不适合胆小的人:如果你犯了一个错误,你可能会损坏你的文件系统。请务必查阅官方文档和dmsetup手册页,三重检查您正在运行的命令,并进行备份!
Linux 内核有一个很棒的工具,称为设备映射器,它可以做一些不错的事情,例如创建作为其他块设备“视图”的块设备,当然还有快照。这也是 LVM 在幕后用来完成繁重工作的方法。
在下面的示例中,我假设您想要快照/home,它是位于 上的 ext4 文件系统/dev/sda2。
首先,找到分区挂载的设备映射器设备的名称:
# mount | grep home
/dev/mapper/home on /home type ext4 (rw,relatime,data=ordered)
Run Code Online (Sandbox Code Playgroud)
这里,设备映射器设备名称是home。如果块设备的路径不以 开头/dev/mapper/,那么您将需要创建一个设备映射器设备,并重新挂载文件系统以使用该设备而不是 HDD 分区。您只需执行一次此操作。
# dmsetup create home --table "0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0"
# umount /home
# mount -t ext4 /dev/mapper/home /home
Run Code Online (Sandbox Code Playgroud)
接下来,获取块设备的设备映射表:
# dmsetup table home
home: 0 3864024960 linear 9:2 0
Run Code Online (Sandbox Code Playgroud)
您的数字可能会有所不同。设备目标应该是linear;如果您的不是,您可能需要特别考虑。如果最后一个数字(起始偏移量)不为 0,则需要创建一个中间块设备(与当前块设备具有相同的表)并使用它作为基础而不是/dev/sda2.
在上面的示例中,home使用带有linear目标的单条目表。您需要将此表替换为使用snapshot目标的新表。
设备映射器提供三个快照目标:
目标snapshot,将写入保存到指定的 COW 设备。(请注意,尽管它被称为快照,但该术语具有误导性,因为快照将是可写的,但底层设备将保持不变。)
目标snapshot-origin将写入发送到底层设备,同时还将写入覆盖的旧数据发送到指定的 COW 设备。
通常,您会创建home一个目标,然后在其之上snapshot-origin创建一些目标。snapshot这就是 LVM 的作用。然而,更简单的方法是直接创建一个snapshot目标,这就是我将在下面展示的内容。
无论您选择哪种方法,都不能写入底层设备 ( /dev/sda2),否则快照将看到文件系统的损坏视图。因此,作为预防措施,您应该将底层块设备标记为只读:
# blockdev --setro /dev/sda2
Run Code Online (Sandbox Code Playgroud)
这不会影响它支持的设备映射器设备,因此如果您已经重新安装/home在 上/dev/mapper/home,它应该不会产生明显的影响。
接下来,您需要准备 COW 设备,该设备将存储自创建快照以来的更改。这必须是块设备,但可以由稀疏文件支持。如果您想使用例如 32GB 的稀疏文件:
# dd if=/dev/zero bs=1M count=0 seek=32768 of=/home_cow
# losetup --find --show /home_cow
/dev/loop0
Run Code Online (Sandbox Code Playgroud)
显然,稀疏文件不应该位于您正在快照的文件系统上:)
现在您可以重新加载设备的表并将其变成快照设备:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot /dev/sda2 /dev/loop0 PO 8" && \
dmsetup resume home
Run Code Online (Sandbox Code Playgroud)
如果成功,新的写入/home现在应该记录在/home_cow文件中,而不是写入/dev/sda2. 确保监视 COW 文件的大小以及其所在文件系统上的可用空间,以避免耗尽 COW 空间。
一旦不再需要快照,您可以合并它(将 COW 文件中的更改永久提交到底层设备),或者丢弃它。
合并它:
将表替换为snapshot-merge目标而不是目标snapshot:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot-merge /dev/sda2 /dev/loop0 P 8" && \
dmsetup resume home
Run Code Online (Sandbox Code Playgroud)接下来,监视合并的状态,直到所有非元数据块都合并:
# watch dmsetup status home
...
0 3864024960 snapshot-merge 281688/2097152 1104
Run Code Online (Sandbox Code Playgroud)
请注意末尾的 3 个数字 (X/YZ)。当 X = Z 时合并完成。
接下来,再次用线性目标替换表格:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0" && \
dmsetup resume home
Run Code Online (Sandbox Code Playgroud)现在你可以拆除循环设备了:
# losetup -d /dev/loop0
Run Code Online (Sandbox Code Playgroud)最后,您可以删除COW文件。
# rm /home_cow
Run Code Online (Sandbox Code Playgroud)要放弃快照,请 unmount /home,按照上面的步骤 3-5 操作,然后重新 mount /home。尽管设备映射器将允许您在不卸载的情况下执行此操作/home,但它没有意义(因为内存中正在运行的程序的状态将不再对应于文件系统状态),并且它可能会损坏您的文件系统。
我知道 RedHat Enterprise、Fedora 和 CentOS 中的 ext3 和 ext4 在创建 LVM 快照时会自动设置检查点。这意味着安装快照永远不会出现任何问题,因为它始终是干净的。
我相信XFS也有同样的支持。我不确定其他文件系统。