I was playing with my LVM thin installation. Created multiple snapshots, merged them with origin many times. At some point in the output of lvs -a
command oldest snapshots lost its origin. In the output of more detailed command lvs -a -o time,name,origin,lv_role
this snapshots are now have lv_role
as public
(while snapshots have roles public,snapshot,thinsnapshot
). merge
is now not possible with error is not a mergeable logical volume
. Now I have multiple questions:
- is this orphaned snapshots are proper volumes or they are corrupted?
- why does this happen? (I was merging some middle in terms of creation time snapshots with their origin and then recreating them)
- can I manually remove origin from a snapshot to make it separated volume?
- is there a way back for this volumes to became snapshots with equal blocks of data being linked to origin again to preserve space?
Update. Test script.
initial config with name of VG and pool that should exist:
VG=vg
Pool="${VG}"/pool0
Test_volume="test"
create test LV and make it random
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
output:
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
now merge one snapshot:
lvconvert --merge "${VG}/${Test_volume}_snap_2"
lvs -a -o name,origin,lv_role| grep "${Test_volume}"
output:
test public
test_snap_0 public
test_snap_1 public
test_snap_3 public
this snapshots are now just volumes, they may share some blocks with each other, sha256sum
shows that data are intact, overriding one does not affect others.
It's quite strange why they lose origin but still have common data blocks.
When two thinly provisioned volumes have shared data blocks, it doesn't imply that one must be an origin of another, or that both of them must have the same origin (at the moment; it is most likely they had the same origin in the past).
To demonstrate this I'll create a setup like yours:
except that I made test and test_snap_1 to share the first 4M:
and made test_snap_0 and test_snap_1 to share second 4M:
The third 4 MiB region is shared by all three.
Now, merging
test_snap_0
:The
test_snap_1
was based on formertest
, which was removed and replaced with other volume, so nowtest_snap_1
has nothing to be based on. But its data is still as it should:To verify that these blocks are still shared, we'll dump thin pool metadata:
Here
dev_id="4"
istest
, anddev_id="5"
istest_snap_1
(can be identified using/etc/lvm/backup/vg
). The dev 4 maps where the former origin was residing, to the "physical" chunks (stored inpool0_tdata
) from 0 to 192. Whereas, the first 64 chunks of dev 5 map to some space past this stretch. But 128 chunks of dev 5 starting from 64 actually point to the same place as they do in dev 4, e.g. these chunks are shared. Notice that these are "thin lvm" chunks, of 64KiB size each (which is default, can be set when creating the thin pool and queried usinglvs -o name,chunksize
); 128 * 64KiB gives 8MiB — that was the size of the region which is actually shared (remembering, third 4MiB was the same on all three volumes).If I rewrite the second 4MiB region of one volume, regions will be unshared and the data on the other volume won't be touched, correctly implementing the CoW semantic. But if I later make them same again, they won't magically merge back into a shared region. In principle, it should be possible to create a deduplication tool for thin LVM, which will merge same blocks into shared, saving some space, even without the new VDO technology, but I know of no such tool.
References: