TT Lab
开始
学习 学习路径 课程

存储实务 — RAID、快照、iSCSI、fio

先铺好回退之路 — LVM 快照、文件系统选择、精简配置

在 TT Lab 中继续学习

一句话总结

变更之前创建的 LVM 快照,几秒钟就能造出“可以回滚”。但快照空间一满就失效,它不是备份,而且和原卷在同一块磁盘上。选择文件系统时必须一并看能否缩小,而精简配置是在承诺并不存在的空间,所以必须配套监控。

为什么需要它

软件包升级、批量修改配置文件、修改 schema 这类操作,都是以“出错就回滚”为前提获得批准的。但如果回滚的办法只有“从备份恢复”,就要花一个小时,期间新进来的数据会丢失。我们需要一种手段:在操作之前瞬间固定卷的样子,失败时回到那一刻。这就是快照。

还有一点。卷划得宽裕,之后另一个卷需要空间,这种事很常见。这时如果选的是“无法缩小的文件系统”,选择就只剩重新创建再迁移。文件系统的选择在一开始就决定了,而且会持续很久。

工作原理

COW 快照。 lvcreate(8) 的 -s 会为原 LV 创建快照。创建的那一刻不会复制任何东西。之后原卷的某个块第一次被修改时,会把旧内容移到快照空间,这就是 copy-on-write 方式。所以快照的大小(-L)不是按原卷大小,而是按“保留快照期间会变化的量”来定。lvs 的 Data% 列显示它用掉了多少空间,到达 100% 时快照会失效并被丢弃。大型操作期间快照悄悄失效,就会在不知道已经没有退路的情况下继续操作。

回滚就是合并。 lvconvert(8) 的 --merge 会把快照的内容写回原卷并删除快照。如果原卷处于打开状态(已挂载),合并会推迟到下一次激活,所以作业计划书里要按“卸载 → 合并 → 重新挂载”的顺序写。合并结束后,快照 LV 会从列表中消失。

快照不是备份。 它与原卷在同一个 VG,通常也在同一块磁盘上。磁盘坏了,原卷和快照会一起消失。而且在 COW 快照存在期间,原卷的每次首次写入都会多发生一次复制,写入变慢。所以快照只在作业窗口期间保留,结束后就删除。

选择文件系统时要看什么。 两者都是日志式文件系统,也都能在挂载状态下扩容。差别出现在缩小时。

ext4 XFS
在线扩容 resize2fs xfs_growfs(仅限挂载状态)
缩小 卸载后可用 resize2fs 完成 设计时按不在支持范围内来考虑——重新创建再迁移
常见默认值 Debian、Ubuntu RHEL 系

resize2fs(8) 可以扩大已挂载的 ext4,缩小则只能在卸载状态下进行。xfs_growfs(8) 顾名思义是扩容工具。最近的 xfsprogs 加入了只缩小最后一个分配组空闲空间的实验功能,但在生产设计中要以“XFS 不能缩小”为前提。

缩小时顺序攸关成败。先把文件系统缩到比目标更小,然后缩小 LV,最后再把文件系统调整到与 LV 相同的大小。 如果先缩小 LV,文件系统的末尾部分就会被截掉。lvreduce -r 把这个过程交给 fsadm 一次完成,但必须明白发生了什么才能使用。

精简配置。 lvmthin(7) 的精简池(thin pool)是拥有实际空间的池,精简卷(thin volume)则在写入时才从这个池里获得空间。所以可以在 400MiB 的池上创建 1GiB 的精简卷。这就是过量分配(overprovisioning)。它依赖的是“多个卷不会全部写满”的统计规律,与虚拟化中的内存超分(overcommit)是同一种交易。lvmthin(7) 警告池写满后写入会停止或报错,并介绍了监控池使用率并自动扩容的配置(thin_pool_autoextend_threshold)。如果 VG 已经没有可用来扩容池的余量,这项配置也没有用。

在现场相遇的样子

很多团队会把快照写进变更作业计划书的“前置作业”一栏。好的计划书会写明快照大小的依据(对作业将修改量的估算),以及“快照使用率超过百分之几就中止”的标准。还会写上作业结束后删除快照的一行。被忘记删除的快照,几周后涨到 100% 而失效,或者一直在拖慢写入性能,这种情况很常见。

“把这个卷缩小一半,让给旁边的卷”这样的请求在 XFS 面前卡住,也经常能看到。因为 RHEL 系的默认值是 XFS,安装时不加思考就选了它。如果是有可能要缩小的卷,就从一开始选 ext4,或者不要划得宽裕,而是从小处起步再逐步扩容来设计。

下一项实验要做什么

用 3GiB 的回环设备建立 VG vg_sto,在 XFS 卷 lv_app 中放入配置文件和订单文件。创建快照后故意做一次错误变更,记录快照使用率,再通过合并回滚。接着在线扩容 XFS,创建 ext4 卷,在保住数据的前提下离线缩小。最后在 400MiB 的精简池上创建 1GiB 的精简卷,亲眼看一看过量分配。