对于大多数Linux文件系统,您不必做任何事情。它应该可以在您不做任何努力的情况下正常工作。快照命令本身会查找使用正在进行快照的卷的已挂载文件系统,并调用一个特殊的钩子来以一致、可挂载的状态检查点它们,并原子地进行快照。
较旧版本的LVM附带了一组VFS锁定补丁,这些补丁将修补各种文件系统,使它们可以为快照进行检查点。但是,在新的内核中,这应该已经内置在大多数Linux文件系统中。
这个有关快照的介绍也这样声称。
进一步的研究表明,在2.6系列内核中,ext系列的文件系统都应该支持此功能。ReiserFS 也可能支持该功能。如果我了解btrfs的开发者,那么它也可能支持该功能。
以下说明相当低级,但如果您想要快照一个不在 LVM 卷上的文件系统,并且无法将其移动到新的 LVM 卷中,则可能会很有用。但是,它们不适合胆小的人:如果您犯了一个错误,可能会损坏文件系统。请务必查阅官方文档和dmsetup
手册,三次检查您正在运行的命令,并备份!
Linux 内核有一个称为 Device Mapper 的强大工具,可以创建作为其他块设备“视图”的块设备,当然还包括快照。它也是 LVM 在后台执行重要操作的工具。
在下面的示例中,我们假设要对位于/dev/sda2
上的 ext4 文件系统 /home
进行快照。
首先,找到分区所挂载的设备映射器设备的名称:
# mount | grep home
/dev/mapper/home on /home type ext4 (rw,relatime,data=ordered)
在这里,设备映射器设备名称为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
接下来,获取块设备的设备映射表:
# dmsetup table home
home: 0 3864024960 linear 9:2 0
linear
;如果您的设备目标不是这样,您可能需要考虑特殊情况。如果最后一个数字(起始偏移量)不是0,则需要创建一个中间块设备(具有与当前设备相同的表),并将其用作基础,而不是/dev/sda2
。home
使用带有linear
目标的单个条目表。您需要用一个新的表替换这个表,该表使用snapshot
目标。快照目标snapshot
,它保存对指定COW设备的写入。(请注意,即使它被称为快照,术语是误导性的,因为快照将是可写的,但底层设备将保持不变。)
快照源目标snapshot-origin
,它将写入发送到底层设备,但也将覆盖写入的旧数据发送到指定的COW设备。
home
成为snapshot-origin
目标,然后在其上创建一些snapshot
目标。这是LVM所做的。但是,更简单的方法是直接创建一个snapshot
目标,这就是我将在下面展示的内容。/dev/sda2
),否则快照将看到文件系统的损坏视图。因此,作为预防措施,您应将底层块设备标记为只读。# blockdev --setro /dev/sda2
这不会影响由设备映射支持的设备,因此如果您已经将/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
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot /dev/sda2 /dev/loop0 PO 8" && \
dmsetup resume home
/home
的新写入应该会记录在/home_cow
文件中,而不是写入/dev/sda2
。请确保监视COW文件的大小以及其所在的文件系统的可用空间,以避免COW空间不足。To merge it:
replace the table with a snapshot-merge
target instead of a snapshot
target:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot-merge /dev/sda2 /dev/loop0 P 8" && \
dmsetup resume home
Next, monitor the status of the merge until all non-metadata blocks are merged:
# watch dmsetup status home
...
0 3864024960 snapshot-merge 281688/2097152 1104
Note the 3 numbers at the end (X/Y Z). The merge is complete when X = Z.
Next, replace the table with a linear target again:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0" && \
dmsetup resume home
Now you can dismantle the loop device:
# losetup -d /dev/loop0
Finally, you can delete the COW file.
# rm /home_cow
To discard the snapshot, unmount /home
, follow steps 3-5 above, and remount /home
. Although Device Mapper will allow you to do this without unmounting /home
, it doesn't make sense (since the running programs' state in memory won't correspond to the filesystem state any more), and it will likely corrupt your filesystem.
blockdev --setro /dev/sda2
调用的一部分。 - liorisnapshot
和 snapshot-origin
)不会针对它们所基于的设备提供起始参数。但是,linear
目标可以提供。实际上,您需要先切掉您需要处理的磁盘部分(在该示例中为 sda2
)。在实践中,我认为这永远不会成为问题,因为当您挂载一个分区时,您将使用整个分区的数据。 - Vladimir Panteleev这取决于您使用的文件系统。如果使用XFS文件系统,您可以使用xfs_freeze -f
命令同步和冻结文件系统,然后使用xfs_freeze -u
命令重新激活它,这样您就可以从冻结的卷创建快照,这应该是一个安全状态。
我不确定这是否对您有帮助,但是您可以将文件系统重新挂载为只读。使用mount -o remount,ro /lvm
(或类似命令)即可实现。 在完成快照后,可以使用mount -o remount,rw /lvm
重新挂载为读写模式。
只要你不在任何类型的专业环境中工作,文件系统损坏是“高度不可能”的。否则,你将会面对现实,你可能会试图责怪“位烂”或“硬件”或其他任何东西,但这归根结底是因为你没有负责任。 正确定义的冻结/解冻(如前面提到的,在数据库环境之外)就足够了。对于数据库,你仍然无法获得完整的事务备份,如果你认为还原时回滚一些事务的备份就可以了:请看起始句子。 根据活动情况,如果需要这个备份,你可能会增加另外5-10分钟的停机时间。 我们大多数人都能轻松承担这一点,但这不能成为普遍建议。 诚实面对缺点吧,伙计们。