LVM Snapshot without copy-on-write

backuplvmsnapshot

I've been experimenting with LVM and how I can use it for managing data on my NFS server. With everything that I've read about snapshots, I am still unsure about how they perform in real life. Why does one need to allocate space in the snapshot if they are just a bunch of pointers to the original data? What is the point of the snapshot if modifying files on the origin also trigger modification on the snapshot via copy-on-write? I thought that the snapshot is supposed to be a "static" point in time of the original.

My expectation is such:

$ ls origin-data
> file1 file2
$ snapshot origin-data to origin-data-snapshot
$ modify origin-data and add new stuff
$ ls origin-data
> file1-modified file2 file3 file4
$ ls origin-data-snapshot
> file1 file2
$ sizeof origin-data-snapshot
> 0 bytes because they're all just pointers to blocks in origin-data!

If I'm misunderstanding, please explain and also explain how snapshots could be used in the way I'm expecting (like git commits, static, non-changing, pointers to data in a point in time that don't care about changes made to the origin). Does it involve RO or RW snapshots?

UPDATE: I've been experimenting with some test partitions and have a bit more understanding. While mounting both origin and it's snapshot, new files in origin obviously show up in something like df -h but not in the snapshot. Meanwhile, lvdisplay shows this percentage for "Allocated to snapshot" increasing. Using 10mb test files and 1gb test partitions, I see exactly how this percentage behaves in relation to my data, but why must this be so? Why does the new data show up on the snapshot and not origin? I would think the blocks behave like hard-links in that old data stays there because the snapshot points to it while new blocks are created next to them because origin points to the new and modified block. No?

Best Answer

The cost of a snapshot cannot possibly be zero bytes. When a block is changed in the source volume, and you have a snapshot, a copy of the original block prior to modification must be made - the original data must be available somehwere so that it's accessible from the snapshot.

That's what the snapshot size is (plus some metadata): original copies of blocks that have since been changed in the source.

Note that it might be an "accounting trick": an implementation could choose not to overwrite the original block on disk, but rather store the new data somewhere else and update the source block list (or whatever it is it uses to track). In this case the snapshot is "static" as per your definition. But it still causes the overall number of allocated blocks to grow whenever a source block is modified. This space usage should be (an is) accounted against the snapshot.

This is true both for RO and RW snapshots, except that it's a bit more complex in the RW case (you don't want to overwrite a block that was modified in the snapshot by an original block from the source if that is modified too, for example).

Related Question