AlmaLinux 10:用 LVM 快照做升级回滚
在 AlmaLinux 10.2 虚拟机(内核 6.12.0-211.64.1.el10_2,LVM 2.03.36)中实测完整流程:建 LV、写文件、冻结打快照、只读挂载核对、删除文件、merge 回滚、重新挂载验证。日志:plans/content-expansion/evidence/logs/alma-lvm-snapshot.log。
快照当回滚点的前提
Section titled “快照当回滚点的前提”升级前打快照,出事时 lvconvert --merge 回滚——但前提是快照本身一致。挂载中的文件系统直接打快照,可能拍到「日志未落盘」的中间状态,回滚后文件系统反而损坏。
所以顺序是:冻结 → 打快照 → 解冻 → 升级。
sudo fsfreeze -f /mnt/datasudo lvcreate -y -s -L 300M -n snap /dev/vglab/datasudo fsfreeze -u /mnt/data-L 300M 是 COW 空间:源卷写入越多,快照消耗越快;写满后快照失效(lvs 会显示 Data% 100)。升级类操作要留足够余量,或升级期间不写业务数据。
只读核对快照内容
Section titled “只读核对快照内容”sudo mount -o ro,nouuid /dev/vglab/snap /mnt/snapls /mnt/snapcat /mnt/snap/a.txta.txtbefore-snapshotnouuid 解决同 UUID 无法同时挂载的问题;ro 保证不会往快照里写。升级前用这一步确认「快照里确实是当前状态」。
回滚:merge 之后不能马上挂载
Section titled “回滚:merge 之后不能马上挂载”sudo umount /mnt/datasudo lvconvert --merge /dev/vglab/snapsudo lvchange -an vglab/datasudo lvchange -ay vglab/dataMerging of volume vglab/snap started.vglab/data: Merged: 100.00%实测:只 lvchange -ay 后 mount 会报 already mounted or mount point busy;必须 -an 再 -ay(完整去激活/再激活)。这一步把「merge 完成」和「卷可挂载」区分开。

sudo mount /dev/vglab/data /mnt/datals /mnt/datacat /mnt/data/a.txtls /mnt/data/b.txta.txtbefore-snapshotls: cannot access '/mnt/data/b.txt': No such file or directory快照后的写入(b.txt)消失,快照时的文件(a.txt)恢复。回滚验证必须看到这个结果,不能只信 merge 百分比。
升级场景的实操顺序
Section titled “升级场景的实操顺序”- 卸载业务挂载或停止写入(数据库用
fsfreeze或停库); fsfreeze -f→lvcreate -s→fsfreeze -u;mount -o ro,nouuid核对快照内容;- 执行升级(
dnf upgrade); - 失败则
umount→lvconvert --merge→lvchange -an/-ay→ 挂载校验; - 成功后
lvremove快照,释放 COW 空间。
可播放的完整时序
Section titled “可播放的完整时序”下面这段终端录制把「建卷 → freeze → 打快照 → 改数据 → 读快照 → merge → 重新激活 → 校验」一次放完(.cast 只有 885 字节,默认不自动播放):
文字版(命令与输出) / Text transcript
# 1. build a loop-backed LV for the labtruncate -s 1G /var/tmp/cast.imgpvcreate -y "$L"; vgcreate vglab "$L"; lvcreate -y -L 800M -n data vglabmkfs.xfs -q /dev/vglab/data; mount /dev/vglab/data /mnt/dataecho before > /mnt/data/a.txt
# 2. freeze, snapshot, unfreezefsfreeze -f /mnt/datalvcreate -y -s -L 200M -n snap /dev/vglab/datafsfreeze -u /mnt/dataLV LSize Attrdata 800.00m owi-aos---snap 200.00m swi-a-s---
# 3. change the origin, then read the snapshotecho after > /mnt/data/b.txt; rm -f /mnt/data/a.txtmount -o ro,nouuid /dev/vglab/snap /mnt/snapcat /mnt/snap/a.txt # before
# 4. merge back and reactivatelvconvert --merge /dev/vglab/snapvglab/data: Merged: 100.00%lvchange -an vglab/data; lvchange -ay vglab/data
# 5. verify the rollbackcat /mnt/data/a.txt # before- COW 空间不足:升级期间大量写入把 300M 用满,快照失效;
- 忘了 fsfreeze:快照回滚后文件系统不一致;
- merge 后直接 mount:EBUSY,先
-an再-ay; - 快照留着不删:长期占用空间并拖慢源卷写性能。
练习:模拟一次「升级失败回滚」
Section titled “练习:模拟一次「升级失败回滚」”sudo dnf install -y lvm2 xfsprogstruncate -s 2G /var/tmp/snap.imgL=$(sudo losetup -f --show /var/tmp/snap.img)sudo pvcreate -y "$L" && sudo vgcreate vglab "$L"sudo lvcreate -y -L 1G -n data vglab && sudo mkfs.xfs -q /dev/vglab/datasudo mkdir -p /mnt/data /mnt/snap && sudo mount /dev/vglab/data /mnt/dataecho good | sudo tee /mnt/data/app.conf >/dev/null && syncsudo fsfreeze -f /mnt/data && sudo lvcreate -y -s -L 300M -n snap /dev/vglab/data && sudo fsfreeze -u /mnt/dataecho broken | sudo tee /mnt/data/app.conf >/dev/null # 模拟升级写坏配置sudo umount /mnt/data && sudo lvconvert --merge /dev/vglab/snapsudo lvchange -an vglab/data && sudo lvchange -ay vglab/datasudo mount /dev/vglab/data /mnt/data && cat /mnt/data/app.conf检查:
lvs中快照Data%很小(说明 COW 空间充足)- 回滚后
app.conf内容恢复为good mount -o ro,nouuid能读到快照内good- 清理后
vgs不再有 vglab
常见问题
快照空间要留多少?
至少覆盖升级期间的写入量。COW 空间写满后快照失效(Data% 到 100),回滚就不可用了;保守做法是按源卷已用空间的 20–30% 起步。
为什么 merge 后要 lvchange -an 再 -ay?
实测 merge 完成后设备状态没完全就绪,直接挂载报 EBUSY;完整去激活再激活会重新建立设备映射,之后挂载正常。
快照能当备份吗?
不能。快照与原卷在同一存储上,盘坏了一起丢;它只适合做升级/变更前的短期回滚点。