Linux环境做LVM快照

目录:

1、功能介绍

在 Linux环境中,快照的核心价值在于不中断服务的前提下,为系统或数据卷保留一个"时间点副本"。如果升级失败,你可以快速回滚到这个副本状态。

LVM(逻辑卷管理):最通用的方案。如果你的服务器磁盘是用 LVM 管理的(许多 RHEL/CentOS 默认如此),优先用它。

2、LVM 快照(通用性最强)

LVM 快照采用写时复制技术,创建瞬间几乎不占空间,之后只记录原卷的变化量。核心命令是 lvcreate。

2.1、创建快照

为你的业务卷(假设是 /dev/vg_data/lv_web)创建一个有足够空间的快照。预留空间通常建议为原卷的 15% 到 30%,如果升级期间写入量大,需留更多。

powershell 复制代码
sudo lvcreate -s -n snap-upgrade -L 20G /dev/vg_data/lv_web

参数 -s 表示快照,-n 是快照名,-L 20G 是分配给快照的空间。

2.2、确认状态

用 lvs 命令查看快照,确保状态是 active 且没有被写满(数据百分比别到 100%)。

2.3、执行升级

快照创建后,原卷可以正常读写,业务不中断。你现在可以放心地执行服务升级操作。

2.4、回滚(如果升级失败)

先将原卷所在文件系统卸载(如果可能),然后合并快照。对于根分区等无法卸载的卷,合并会在重启时完成。

powershell 复制代码
sudo umount /path/to/mount  # 如果原卷已挂载,先卸载
sudo lvconvert --merge /dev/vg_data/snap-upgrade  #把快照里的数据合并回原卷
sudo reboot                 # 如果无法卸载,重启让合并生效

2.5、清理

如果升级成功,删除快照释放空间。

powershell 复制代码
sudo lvremove /dev/vg_data/snap-upgrade

3、实际项目做快照

实际的项目是服务不在根分区,而是在 /data 分区,并且用 Docker 运行,那么对 /data 分区做快照就是正确的一步------因为服务的数据和容器运行时都落在这上面。

3.1、data 卷做快照

powershell 复制代码
# 假设 /data 对应的逻辑卷是 /dev/vg_data/lv_data
sudo lvcreate -L 20G -s -n data-snap /dev/vg_data/lv_data

但 Docker 场景下有一个额外问题:Docker 容器在运行中,数据卷里可能还有未落盘的缓存。

LVM 快照是"崩溃一致性"的,意思是它保存的是快照瞬间磁盘上的状态。如果容器里的数据库(比如 MySQL、PostgreSQL)还有数据在内存缓存里没写进磁盘,快照拿到的就是"不一致"的状态。回滚后数据库可能起不来,或者需要恢复日志。

所以关键操作是:在创建快照前,让应用层把数据刷到磁盘。

不同服务做法不同:

  • MySQL:执行 FLUSH TABLES WITH READ LOCK,或者用 mysqldump 先导出一份逻辑备份。

  • PostgreSQL:执行 CHECKPOINT。

  • Redis:执行 BGSAVE 或 SAVE。

  • 纯文件服务(无数据库):风险较小,但最好也先停止写入。

如果你无法让应用停写,一个更简单的做法是:先用 docker commit 或 docker save 把容器镜像备份一份,数据卷单独用 tar 或 rsync 做逻辑备份,而不是依赖 LVM 快照回滚。

3.3、tar备份命令示例:

powershell 复制代码
# 先停掉使用该卷的容器,确保数据一致
docker stop <容器名>

# 创建备份文件,卷挂载为只读(:ro),避免备份过程被意外修改
docker run --rm \
  -v <你的卷名>:/data:ro \
  -v /你的备份目录:/backup \
  alpine tar czf /backup/<卷名>-$(date +%Y%m%d).tar.gz -C /data .

3.4、tar恢复命令示例:

powershell 复制代码
# 先创建目标卷(如果卷已存在且有数据,先清空或换新卷名)
docker volume create <卷名>

# 把 tar 包解压回卷
docker run --rm \
  -v <卷名>:/target \
  -v /你的备份目录:/backup:ro \
  alpine tar xzf /backup/<卷名>-20260915.tar.gz -C /target

3.5、 rsync备份命令示例:

powershell 复制代码
# 先停容器
docker stop <容器名>

# 找到真实路径
VOL_PATH=$(docker volume inspect <卷名> --format '{{.Mountpoint}}')

# 用 rsync 做镜像式备份
sudo rsync -avh --delete \
  --one-file-system \
  "$VOL_PATH/" \
  /你的备份目录/<卷名>/

3.6、 rsync恢复命令示例:

powershell 复制代码
# 停容器后,把备份目录同步回卷路径
sudo rsync -avh --delete \
  /你的备份目录/<卷名>/ \
  "$VOL_PATH/"

3.7、总结选型

相关推荐
小师兄吃牛肉6 天前
C++ 与 Lua 的协程交互:从原理到实战
c++·lua·交互
喜欢的名字被抢了6 天前
09-Redis 进阶原理篇:单线程、多线程、过期、LRU-LFU、Fork 与 Lua
数据库·redis·lua
白山编程大哥6 天前
Lua 中使用 C 语言的用户自定义类型——userdata
c语言·junit·lua
大侠归来9 天前
C++ 与 Lua 的协程交互:从原理到实战
c++·lua·交互
疯狂成瘾者9 天前
海康 Artemis 接口对接
开发语言·lua
一线灵10 天前
跨平台游戏引擎 Axmol-2.11.5 发布
游戏引擎·lua
liulilittle18 天前
麻将结算全链路语义(SETTLE_SEMANTICS)
ai·自动化·llm·mock·lua·测试
liulilittle19 天前
麻将服务器崩溃补偿与异常处理语义(CRASH_SEMANTICS)
ai·自动化·llm·mock·lua·测试·tools
liulilittle19 天前
麻将 UI 层可观察行为(UI_BEHAVIOR)
ai·自动化·llm·mock·lua·测试·tools
liulilittle19 天前
C++ 引擎接口到 mock 的映射(INTERFACE_MAP)
ai·自动化·llm·mock·lua·测试·tools