我正在玩我的 LVM 精简安装。创建多个快照,并将它们多次与原点合并。在命令输出中的某个时刻,lvs -a
最旧的快照丢失了其起源。在更详细命令的输出中,lvs -a -o time,name,origin,lv_role
此快照现在具有lv_role
(public
而快照具有 Roles public,snapshot,thinsnapshot
)。merge
现在不可能出现错误is not a mergeable logical volume
。现在我有多个问题:
- 这个孤立的快照是正确的卷还是已损坏?
- 为什么会发生这种情况?(我将创建时间快照的一些中间部分与其起源合并,然后重新创建它们)
- 我可以手动从快照中删除源以使其成为单独的卷吗?
- 有没有办法让这些卷成为快照,并将相同的数据块再次链接到原点以保留空间?
更新。测试脚本。
带有 VG 名称和应该存在的池的初始配置:
VG=vg
Pool="${VG}"/pool0
Test_volume="test"
创建测试 LV 并使其随机
lvcreate -V10M -T "${Pool}" -n "${Test_volume}"
lvchange -ay -Ky "${VG}"/"${Test_volume}"
dd if=/dev/urandom of="/dev/${VG}/${Test_volume}"
lvcreate -n "${Test_volume}_snap_0" --snapshot "${VG}"/"${Test_volume}"
lvchange -ay -Ky "${VG}"/"${Test_volume}_snap_0"
dd if=/dev/urandom of="/dev/${VG}/${Test_volume}"
lvcreate -n "${Test_volume}_snap_1" --snapshot "${VG}"/"${Test_volume}"
lvchange -ay -Ky "${VG}"/"${Test_volume}_snap_1"
dd if=/dev/urandom of="/dev/${VG}/${Test_volume}"
lvcreate -n "${Test_volume}_snap_2" --snapshot "${VG}"/"${Test_volume}"
lvchange -ay -Ky "${VG}"/"${Test_volume}_snap_2"
dd if=/dev/urandom of="/dev/${VG}/${Test_volume}"
lvcreate -n "${Test_volume}_snap_3" --snapshot "${VG}"/"${Test_volume}"
lvchange -ay -Ky "${VG}"/"${Test_volume}_snap_3"
sha256sum "/dev/${VG}/${Test_volume}_snap"*
lvs -a -o name,origin,lv_role| grep "${Test_volume}"
lvs
输出:
test public,origin,thinorigin,multithinorigin
test_snap_0 test public,snapshot,thinsnapshot
test_snap_1 test public,snapshot,thinsnapshot
test_snap_2 test public,snapshot,thinsnapshot
test_snap_3 test public,snapshot,thinsnapshot
现在合并一个快照:
lvconvert --merge "${VG}/${Test_volume}_snap_2"
lvs -a -o name,origin,lv_role| grep "${Test_volume}"
输出:
test public
test_snap_0 public
test_snap_1 public
test_snap_3 public
该快照现在只是卷,它们可能彼此共享一些块,sha256sum
表明数据完好无损,覆盖其中一个不会影响其他快照。
很奇怪为什么它们失去了起源但仍然有共同的数据块。
当两个精简配置卷具有共享数据块时,并不意味着一个卷必须是另一个卷的来源,或者它们都必须具有相同的来源(目前;很可能它们在过去的)。
为了演示这一点,我将创建一个像您一样的设置:
除了我做了 test 和 test_snap_1 来共享前 4M:
并使 test_snap_0 和 test_snap_1 共享第二个 4M:
第三个 4 MiB 区域由所有三个区域共享。
现在,合并
test_snap_0
:该书
test_snap_1
是基于前者的test
,后者已被删除并被其他卷取代,因此现在test_snap_1
没有任何依据。但它的数据仍然是应该的:为了验证这些块是否仍然共享,我们将转储精简池元数据:
这里
dev_id="4"
是test
、 和dev_id="5"
是test_snap_1
(可以使用 来识别/etc/lvm/backup/vg
)。dev 4 将先前原点所在的位置映射到pool0_tdata
从 0 到 192 的“物理”块(存储在 中)。而 dev 5 的前 64 个块映射到超出此范围的某个空间。但 dev 5 中从 64 开始的 128 个块实际上与 dev 4 中的指向相同的位置,例如,这些块是共享的。请注意,这些是“thin lvm”块,每个大小为 64KiB(默认值,可以在创建精简池时设置并使用 查询lvs -o name,chunksize
);128 * 64KiB 给出 8MiB — 这是实际共享的区域的大小(记住,第三个 4MiB 在所有三个卷上都是相同的)。如果我重写一个卷的第二个 4MiB 区域,区域将不再共享,并且另一个卷上的数据不会被触及,从而正确实现 CoW 语义。但如果我稍后再次使它们相同,它们将不会神奇地合并回共享区域。原则上,应该可以为精简LVM创建一个重复数据删除工具,它将相同的块合并为共享块,节省一些空间,即使没有新的VDO技术,但我知道没有这样的工具。
参考: