已挂载文件系统的LVM快照

时间:2009-12-21 13:25:03

标签: linux backup filesystems snapshot

我想以编程方式在Linux中制作实时文件系统的快照,最好使用LVM。我不想卸载它,因为我打开了很多文件(我最常见的情况是我有一个繁忙的桌面,有很多程序)。

据我所知,由于内核缓冲区和一般文件系统活动,磁盘上的数据可能处于某种或多或少的未定义状态。

有没有办法“原子地”卸载FS,制作LVM快照并将其挂载?如果操作系统将阻止所有活动几秒钟来执行此任务,那就没问题了。或者也许某种原子“同步+快照”?内核通话?

我不知道是否有可能......

6 个答案:

答案 0 :(得分:11)

对于大多数Linux文件系统,您不应该做任何事情。它应该在你没有任何努力的情况下工作。快照命令本身使用正在快照的卷搜寻已挂载的文件系统,并调用一个特殊的挂钩,以一致的可挂载状态检查它们并以原子方式执行快照。

早期版本的LVM带有一组VFS锁定补丁,可以修补各种文件系统,以便可以为快照检查点。但是新内核应该已经内置到大多数Linux文件系统中。

intro on snapshots声称同样多。

还有一点研究表明,对于2.6系列中的内核,ext系列文件系统应该都支持这一点。 ReiserFS也可能。如果我知道btrfs的人,那个人可能也会这样做。

答案 1 :(得分:4)

我知道RedHat Enterprise,Fedora和CentOS中的ext3和ext4会在创建LVM快照时自动检查点。这意味着安装快照永远不会有任何问题,因为它总是干净的。

相信 XFS具有相同的支持。我不确定其他文件系统。

答案 2 :(得分:3)

这取决于您使用的文件系统。使用XFS,您可以使用xfs_freeze -f来同步和冻结FS,并使用xfs_freeze -u再次激活它,这样您就可以从冻结的卷创建快照,这应该是一个保存状态。

答案 3 :(得分:1)

我不确定这是否适合您,但您可以将文件系统重新安装为只读。 mount -o remount,ro /lvm(或类似的东西)可以解决问题。完成快照后,您可以使用mount -o remount,rw /lvm重新安装读写。

答案 4 :(得分:1)

  

有没有办法“原子地”卸载FS,制作LVM快照并将其挂载?

即使文件系统不在LVM卷上,也可以对挂载的文件系统进行快照。如果文件系统在LVM上,或者它有内置的快照工具(例如btrfs或ZFS),那么请改用它们。

以下说明相当低级,但如果您希望能够对不在LVM卷上的文件系统进行快照,并且无法将其移动到新的LVM卷,则它们非常有用。但是,他们不是为了胆小的人:如果你犯了错误,你可能会破坏你的文件系统。请务必参阅the official documentationdmsetup手册页,三重检查您正在运行的命令,备份

Linux内核有一个很棒的工具叫做Device Mapper,它可以做很好的事情,比如创建块设备,这些设备是其他块设备的“视图”,当然还有快照。这也是LVM在引擎盖下使用的重要工具。

在下面的示例中,我假设您要快照/home,这是位于/dev/sda2的ext4文件系统。

首先,找到安装分区的设备映射器设备的名称:

# 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空间。

一旦您不再需要快照,您可以合并它(将COW文件中的更改永久提交到底层设备),或丢弃它。

  • 要合并它:

    1. 将表替换为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
      
    2. 接下来,监视合并的状态,直到合并所有非元数据块:

      # watch dmsetup status home
      ...
      0 3864024960 snapshot-merge 281688/2097152 1104
      

      注意末尾的3个数字(X / Y Z)。当X = Z时,合并完成。

    3. 接下来,再次使用线性目标替换表格:

      # dmsetup suspend home && \
        dmsetup reload home --table \
          "0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0" && \
        dmsetup resume home
      
    4. 现在您可以拆除循环设备:

      # losetup -d /dev/loop0
      
    5. 最后,您可以删除COW文件。

      # rm /home_cow
      
  • 要放弃快照,请卸载/home,按照上述步骤3-5操作,然后重新安装/home。尽管Device Mapper允许您在不卸载/home的情况下执行此操作,但它没有意义(因为内存中正在运行的程序状态将不再对应于文件系统状态),并且它可能会损坏您的文件系统。

答案 5 :(得分:0)

只要你从不在任何一种专业环境中工作,FS腐败就不太可能了#34;否则你会遇到现实,你可能会试着责备"有点腐烂"或"硬件"或者其他什么,但这一切都归结为不负责任。 冻结/解冻(如前所述,只有在正确调用的情况下)才足够在数据库环境之外。对于数据库,您仍然无法获得事务完成备份,如果您认为备份可以在恢复时回滚某些事务:请参阅开始句子。 根据活动情况,您可能只需添加另一个 5-10分钟的停机时间,如果您需要备份。 我们中的大多数可以轻松承担这一责任,但这不是一般建议。 诚实地说明缺点,伙计。