逻辑卷的瞬时生成、以空间换时间副本

LVM 快照在时间上定格一块块设备

LVM 快照既不是拷贝,也不是 reflink:它是一个挂在源逻辑卷上的、大小固定的写时复制异常存储。lvcreate -s -L 5G -n snap vg/data 从卷组里划走 5 GiB,之后 device-mapper 的 snapshot 目标会在某个源 chunk 第一次被写时,把它的原始内容记录下来。无论源卷多大,创建都是瞬时的,因为创建时什么都没复制。 这个大小就是你全部的安全余量,也正是最常被写错的参数。按“一周内没什么写入”配的存储,会被一次数据库 checkpoint 或一次 rsync 在一小时内吃光;而它填满时快照不会降级,而是直接失效并开始返回 I/O 错误。恢复点恰好在你最需要它的那一刻消失,所以存储的剩余空间该进监控面板,而不是躺在 runbook 里。 异常存储,不是副本 一个经典的 LVM 快照用到两个 device-mapper 目标:源卷被重新映射为 snapshot-origin,另有一个新的 snapshot 设备把它与 COW 设备组合起来。读未改动的 chunk 直接落到源卷;某个 chunk 第一次被写时,旧 chunk 被复制进 COW 设备,然后新数据才写下去。所以消耗量跟“发生过改动的不同 chunk 数”成正比,而不是跟写入次数成正比:fixture 往 16 个热 chunk 写了一百万次,只消耗 15 个异常,约 60 KiB。 ...

四月 10, 2028 · 1 分钟 · XB Field Notes
瞬间抓取文件系统状态、既能快速恢复又近乎零成本的机制

ZFS 快照给文件系统一个回退键

ZFS 快照就是给某个数据集在某个 transaction group 上的块树起的一个名字。它不复制任何东西、不冻结任何东西,代价只是几个元数据块:zfs snapshot tank/data@before-upgrade 会在 shell 提示符重画完之前就返回。由于 ZFS 从不原地覆盖仍在使用的块,旧块树在磁盘上一直有效,直到最后一个引用消失——而快照就是这个引用。 正是这一点让“一墙的每日历史”变得可行,也正是本文标题最危险的地方。快照给你数据的许多个版本,却不给你“池不会丢”这件事的保障。tank/data 的每一份快照都住在 tank 里,所以带走池的那次故障,会在同一瞬间带走数据集和它的全部历史。多版本与多版本安全是两种不同的性质,后者只能由复制来提供。 为一个一致的树命名 快照建立在 transaction group 边界上,所以它捕获的树内部自洽——数据库的文件与元数据冻结在同一瞬间,而不是相差几微秒。-r 会连同所有后代数据集一起打快照,凡是有子数据集的地方都该这么用;否则一个递归布局会在不同层级留下时间不同的快照,层与层之间的增量复制就变得别扭。 名字由你决定,而它是保留策略唯一的抓手:tank/data@daily-2026-09-16 可以按模式清理,自动生成的名字则需要额外记账。zfs list -t snapshot -o name,used,refer,creation -s creation 列出整个快照集以及每一份钉住的空间。 空间在哪里:zfs list -o space ZFS 用一组列来回答唯一重要的问题:这是谁的数据?zfs list -o space tank/data 会给出 USED、USEDSNAP、USEDDS、USEDREFRESERV、USEDCHILD、REFER 与 AVAIL。REFER 是数据集自身需要的量,USEDSNAP 是快照钉住的量,USED 是二者之和。USEDSNAP 持续上涨而 REFER 保持不变,说明吃掉池子的是快照,不是数据。具体到某一份快照,used 是它单独钉住的块,refer 是它能引用到的全部块,两者之差正是与其他版本共用的那部分。 ...

三月 21, 2028 · 1 分钟 · XB Field Notes
一个与源共享未改动数据、改动后才分离的时间点视图。

Btrfs 快照是写时复制,不是复制

btrfs 快照不是任何意义上的复制。btrfs subvolume snapshot 建立的新子卷,其根指向与源完全相同的 extent 树,两边共享的每个 extent 被引用两次、只存一份。创建是一次元数据操作:子卷里装的是 1 GiB 还是 10 TiB,耗时都在毫秒级。 这让快照成为机器上最便宜的回滚原语,也正是它最常被过度信任的原因。空间随分岔增长,而不随数据量增长;代价来得晚,落在别人的写操作上,而且落在保存原始数据的那块设备上。从不清理的快照是一场慢动作的磁盘写满事故,而同盘快照无论留多少份都不是备份。 共享 extent,而不是复制数据块 快照就是子卷,而子卷是拥有自己根的子树,所以快照机制与让 reflink 生效的是同一套引用计数。用 btrfs subvolume snapshot -r /data /snap/data-2026-09-16 打一个只读快照;-r 很关键,因为可写快照在任何一次写入发生的那一刻就开始分岔,而备份目标本来就不该可写。快照与源是平级的子卷,清理用 btrfs subvolume delete /snap/data-2026-09-16;正在被挂载使用的子卷删不掉,btrfs subvolume list -t 能把快照按父子关系列成表,按时间做保留时用得上。 真正花钱的是快照之后的那次写入。任意一侧覆盖一个共享 extent 时,文件系统给写入方分配新 extent,把旧 extent 留给另一侧,所以快照的价格由随后的写入支付,计量单位是这次写入触及的 extent 数,而不是快照命令本身。APFS 的 clonefile 遵循同一规则,fixture 量到的形状是:克隆 64 MiB 花费 0 KiB,普通复制 64 MiB 花费 65536 KiB,覆盖克隆文件前 8 MiB 花费 8192 KiB;而把这 8 MiB 再改写一次花费 0 KiB,因为这些 extent 已经分岔过了。 ...

十一月 14, 2027 · 2 分钟 · XB Field Notes