字数 1387,阅读大约需 7 分钟
LVM 快照是 LVM 最"魔幻"的特性之一——给 LV 拍一张"照片",之后任何修改都不会影响照片里的内容。本篇讲清快照的原理、用法、限制与备份策略。
一、快照是什么?
LVM 快照是 LV 在某一时刻的只读/可写副本。底层机制叫 COW(Copy-On-Write,写时复制):
写入前: [源 LV] 快照 LV(指针共享数据块)
↓
对源 LV 写一个块:
↓
写入前:① 复制原块到快照 LV(snapshot area)
② 在源 LV 写入新数据
读快照 LV 时:
↓
块如果在快照 area:从快照 area 读(旧数据)
块如果不在快照 area:从源 LV 读(未改过)
关键点:
- • 快照本身几乎不占空间,占用随源 LV 的写操作增加
- • 快照是 LV,不是镜像 —— 它不是另一份完整数据
二、创建快照
2.1 基本用法
# 创建名为 lv_demo_snap 的快照,大小 1G
$ lvcreate -L 1G -s -n lv_demo_snap /dev/vg_data/lv_demo
Logical volume "lv_demo_snap" created.
参数:
2.2 验证快照
$ lvs
LV VG Attr LSize Pool Origin Data%
lv_demo vg_data owi-aos--- 5.00g # o = origin
lv_demo_snap vg_data swi-a-s--- 1.00g lv_demo 0.00 # s = snapshot
字段含义:
- •
lv_demo 的 Attr 第一位 o:origin - •
lv_demo_snap 的 Attr 第一位 s:snapshot
2.3 挂载快照
$ mkdir -p /mnt/snap
$ mount -o ro /dev/vg_data/lv_demo_snap /mnt/snap
# 看起来和数据盘一模一样
$ ls /mnt/snap
file1.txt file2.txt ...
# 验证:修改源 LV
$ echo "new data" >> /mnt/lv_demo/file1.txt
# 源 LV 看到的是新内容
$ cat /mnt/lv_demo/file1.txt
new data
# 快照里仍然是旧内容
$ cat /mnt/snap/file1.txt
(原有内容)
三、用快照做备份
这是生产环境最常见的用法:
#!/bin/bash
# 完整流程:快照 → 挂载 → 备份 → 删除
SRC=/dev/vg_data/lv_db
SNAP_NAME=lv_db_snap
SNAP_SIZE=2G
BACKUP_DIR=/backup
DATE=$(date +%Y%m%d)
# 1. 创建快照
lvcreate -L $SNAP_SIZE -s -n $SNAP_NAME $SRC
# 2. 挂载
mkdir -p /mnt/snap
mount -o ro /dev/vg_data/$SNAP_NAME /mnt/snap
# 3. 备份(用 tar 或其他工具)
tar czf $BACKUP_DIR/db-$DATE.tar.gz -C /mnt/snap .
# 4. 卸载并删除快照
umount /mnt/snap
lvremove -f /dev/vg_data/$SNAP_NAME
echo "Backup completed: $BACKUP_DIR/db-$DATE.tar.gz"
核心价值:在备份过程中,应用可以继续写源 LV,不影响数据一致性。
四、快照大小怎么定?
快照大小 = 快照 area 容量 = 你预计源 LV 在快照生命周期内写入的数据量。
估算公式(粗略):
SNAP_SIZE = 写吞吐量 × 备份耗时 + 安全余量
例如:100MB/s × 60s = 6GB
五、快照满了会怎样?
这是关键陷阱:
当 snapshot area 写满,新写入会失败,快照立即失效(变为 invalid)
失效的快照无法恢复,只能删除
监控快照状态:
# 监控所有快照的占用率
$ lvs -o lv_name,origin,data_percent
LV Origin Data%
lv_demo_snap lv_demo 45.32
# 超过 80% 要警惕
# 自动扩容脚本
$ lvextend -L +1G /dev/vg_data/lv_demo_snap
强烈建议:备份脚本里加上"快照超过 80% 自动扩容"的逻辑,否则备份可能中途失败。
六、删除快照
# 方法 1
$ lvremove /dev/vg_data/lv_demo_snap
Do you really want to remove active logical volume vg_data/lv_demo_snap? [y/n]: y
# 方法 2:强制(脚本用)
$ lvremove -f /dev/vg_data/lv_demo_snap
删除快照是秒级操作,不会等 COW 数据写完。
七、Thin Snapshot:传统快照的进化
传统快照(也叫 COW snapshot)的痛点:
Thin snapshot 解决了这些问题(后续会写文章专门介绍):
# 先把源 LV 转成 thin LV(先有 thin pool)
$ lvcreate -L 100G --thinpool tp_data vg_data
$ lvcreate -V 50G --thin -n lv_thin vg_data/tp_data
# thin 快照几乎不占空间
$ lvcreate -s --thin -n lv_thin_snap vg_data/lv_thin
特点:
- • 快照空间从 thin pool 取,没有固定容量上限
八、快照的局限
| |
|---|
| |
| LVM 快照不保证跨多个 LV 的一致性(如数据库需要 redo log + datafile 一起快照) |
| |
| |
九、生产环境快照最佳实践
- 1. 快照 ≠ 备份:快照必须和真实备份(tar / dump / btrfs send / ZFS send)配合使用
- 2. 数据库快照:先
FLUSH TABLES WITH READ LOCK(MySQL)或 pg_dump --snapshot(PG)拿到一致状态,再做快照;或者让数据库自己处理快照一致性(部分数据库可以) - 5. 重要数据:用 thin snapshot + 外部备份(实时同步到另一台机器)
十、本篇小结
| |
|---|
| lvcreate -L 1G -s -n snap /dev/vg/lv |
| mount -o ro /dev/vg/snap /mnt/snap |
| lvs -o lv_name,origin,data_percent |
| lvextend -L +1G /dev/vg/snap |
| lvremove /dev/vg/snap |
口诀: