Image of the glider from the Game of Life by John Conway
Skip to content

ZFS Administration, Part XII- Snapshots and Clones

Table of Contents

Zpool Administration ZFS Administration Appendices
0. Install ZFS on Debian GNU/Linux 9. Copy-on-write A. Visualizing The ZFS Intent Log (ZIL)
1. VDEVs 10. Creating Filesystems B. Using USB Drives
2. RAIDZ 11. Compression and Deduplication C. Why You Should Use ECC RAM
3. The ZFS Intent Log (ZIL) 12. Snapshots and Clones D. The True Cost Of Deduplication
4. The Adjustable Replacement Cache (ARC) 13. Sending and Receiving Filesystems
5. Exporting and Importing Storage Pools 14. ZVOLs
6. Scrub and Resilver 15. iSCSI, NFS and Samba
7. Getting and Setting Properties 16. Getting and Setting Properties
8. Best Practices and Caveats 17. Best Practices and Caveats

Snapshots with ZFS are similar to snapshots with Linux LVM. A snapshot is a first class read-only filesystem. It is a mirrored copy of the state of the filesystem at the time you took the snapshot. Think of it like a digital photograph of the outside world. Even though the world is changing, you have an image of what the world was like at the exact moment you took that photograph. Snapshots behave in a similar manner, except when data changes that was part of the dataset, you keep the original copy in the snapshot itself. This way, you can maintain persistence of that filesystem.

You can keep up to 2^64 snapshots in your pool, ZFS snapshots are persistent across reboots, and they don't require any additional backing store; they use the same storage pool as the rest of your data. If you remember our post about the nature of copy-on-write filesystems, you will remember our discussion about Merkle trees. A ZFS snapshot is a copy of the Merkle tree in that state, except we make sure that the snapshot of that Merkle tree is never modified.

Creating snapshots is near instantaneous, and they are cheap. However, once the data begins to change, the snapshot will begin storing data. If you have multiple snapshots, then multiple deltas will be tracked across all the snapshots. However, depending on your needs, snapshots can still be exceptionally cheap.

Creating Snapshots

You can create two types of snapshots: pool snapshots and dataset snapshots. Which type of snapshot you want to take is up to you. You must give the snapshot a name, however. The syntax for the snapshot name is:

  • pool/dataset@snapshot-name
  • pool@snapshot-name

To create a snapshot, we use the "zfs snapshot" command. For example, to take a snapshot of the "tank/test" dataset, we would issue:

# zfs snapshot tank/test@tuesday

Even though a snapshot is a first class filesystem, it does not contain modifiable properties like standard ZFS datasets or pools. In fact, everything about a snapshot is read-only. For example, if you wished to enable compression on a snapshot, here is what would happen:

# zfs set compression=lzjb tank/test@friday
cannot set property for 'tank/test@friday': this property can not be modified for snapshots

Listing Snapshots

Snapshots can be displayed two ways: by accessing a hidden ".zfs" directory in the root of the dataset, or by using the "zfs list" command. First, let's discuss the hidden directory. Check out this madness:

# ls -a /tank/test
./  ../  boot.tar  text.tar  text.tar.2
# cd /tank/test/.zfs/
# ls -a
./  ../  shares/  snapshot/

Even though the ".zfs" directory was not visible, even with "ls -a", we could still change directory to it. If you wish to have the ".zfs" directory visible, you can change the "snapdir" property on the dataset. The valid values are "hidden" and "visible". By default, it's hidden. Let's change it:

# zfs set snapdir=visible tank/test
# ls -a /tank/test
./  ../  boot.tar  text.tar  text.tar.2  .zfs/

The other way to display snapshots is by using the "zfs list" command, and passing the "-t snapshot" argument, as follows:

# zfs list -t snapshot
NAME                              USED  AVAIL  REFER  MOUNTPOINT
pool/cache@2012:12:18:51:2:19:00      0      -   525M  -
pool/cache@2012:12:18:51:2:19:15      0      -   525M  -
pool/home@2012:12:18:51:2:19:00   18.8M      -  28.6G  -
pool/home@2012:12:18:51:2:19:15   18.3M      -  28.6G  -
pool/log@2012:12:18:51:2:19:00     184K      -  10.4M  -
pool/log@2012:12:18:51:2:19:15     184K      -  10.4M  -
pool/swap@2012:12:18:51:2:19:00       0      -    76K  -
pool/swap@2012:12:18:51:2:19:15       0      -    76K  -
pool/vmsa@2012:12:18:51:2:19:00       0      -  1.12M  -
pool/vmsa@2012:12:18:51:2:19:15       0      -  1.12M  -
pool/vmsb@2012:12:18:51:2:19:00       0      -  1.31M  -
pool/vmsb@2012:12:18:51:2:19:15       0      -  1.31M  -
tank@2012:12:18:51:2:19:00            0      -  43.4K  -
tank@2012:12:18:51:2:19:15            0      -  43.4K  -
tank/test@2012:12:18:51:2:19:00       0      -  37.1M  -
tank/test@2012:12:18:51:2:19:15       0      -  37.1M  -

Notice that by default, it will show all snapshots for all pools.

If you want to be more specific with the output, you can see all snapshots of a given parent, whether it be a dataset, or a storage pool. You only need to pass the "-r" switch for recursion, then provide the parent. In this case, I'll see only the snapshots of the storage pool "tank", and ignore those in "pool":

# zfs list -r -t snapshot tank
NAME                              USED  AVAIL  REFER  MOUNTPOINT
tank@2012:12:18:51:2:19:00           0      -  43.4K  -
tank@2012:12:18:51:2:19:15           0      -  43.4K  -
tank/test@2012:12:18:51:2:19:00      0      -  37.1M  -
tank/test@2012:12:18:51:2:19:15      0      -  37.1M  -

Destroying Snapshots

Just as you would destroy a storage pool, or a ZFS dataset, you use a similar method for destroying snapshots. To destroy a snapshot, use the "zfs destroy" command, and supply the snapshot as an argument that you want to destroy:

# zfs destroy tank/test@2012:12:18:51:2:19:15

An important thing to know, is if a snapshot exists, it's considered a child filesystem to the dataset. As such, you cannot remove a dataset until all snapshots, and nested datasets have been destroyed.

# zfs destroy tank/test
cannot destroy 'tank/test': filesystem has children
use '-r' to destroy the following datasets:

Destroying snapshots can free up additional space that other snapshots may be holding onto, because they are unique to those snapshots.

Renaming Snapshots

You can rename snapshots, however, they must be renamed in the storage pool and ZFS dataset from which they were created. Other than that, renaming snapshots is pretty straight forward:

# zfs rename tank/test@2012:12:18:51:2:19:15 tank/test@tuesday-19:15

Rolling Back to a Snapshot

A discussion about snapshots would not be complete without a discussion about rolling back your filesystem to a previous snapshot.

Rolling back to a previous snapshot will discard any data changes between that snapshot and the current time. Further, by default, you can only rollback to the most recent snapshot. In order to rollback to an earlier snapshot, you must destroy all snapshots between the current time and that snapshot you wish to rollback to. If that's not enough, the filesystem must be unmounted before the rollback can begin. This means downtime.

To rollback the "tank/test" dataset to the "tuesday" snapshot, we would issue:

# zfs rollback tank/test@tuesday
cannot rollback to 'tank/test@tuesday': more recent snapshots exist
use '-r' to force deletion of the following snapshots:

As expected, we must remove the "@wednesday" and "@thursday" snapshots before we can rollback to the "@tuesday" snapshot.

ZFS Clones

A ZFS clone is a writeable filesystem that was "upgraded" from a snapshot. Clones can only be created from snapshots, and a dependency on the snapshot will remain as long as the clone exists. This means that you cannot destroy a snapshot, if you cloned it. The clone relies on the data that the snapshot gives it, to exist. You must destroy the clone before you can destroy the snapshot.

Creating clones is nearly instantaneous, just like snapshots, and initially does not take up any additional space. Instead, it occupies all the initial space of the snapshot. As data is modified in the clone, it begins to take up space separate from the snapshot.

Creating ZFS Clones

Creating a clone is done with the "zfs clone" command, the snapshot to clone, and the name of the new filesystem. The clone does not need to reside in the same dataset as the clone, but it does need to reside in the same storage pool. For example, if I wanted to clone the "tank/test@tuesday" snapshot, and give it the name of "tank/tuesday", I would run the following command:

# zfs clone tank/test@tuesday tank/tuesday
# dd if=/dev/zero of=/tank/tuesday/random.img bs=1M count=100
# zfs list -r tank
tank           161M  2.78G  44.9K  /tank
tank/test     37.1M  2.78G  37.1M  /tank/test
tank/tuesday   124M  2.78G   161M  /tank/tuesday

Destroying Clones

As with destroying datasets or snapshots, we use the "zfs destroy" command. Again, you cannot destroy a snapshot until you destroy the clones. So, if we wanted to destroy the "tank/tuesday" clone:

# zfs destroy tank/tuesday

Just like you would with any other ZFS dataset.

Some Final Thoughts

Because keeping snapshots is very cheap, it's recommended to snapshot your datasets frequently. Sun Microsystems provided a Time Slider that was part of the GNOME Nautilus file manager. Time Slider keeps snapshots in the following manner:

  • frequent- snapshots every 15 mins, keeping 4 snapshots
  • hourly- snapshots every hour, keeping 24 snapshots
  • daily- snapshots every day, keeping 31 snapshots
  • weekly- snapshots every week, keeping 7 snapshots
  • monthly- snapshots every month, keeping 12 snapshots

Unfortunately, Time Slider is not part of the standard GNOME desktop, so it's not available for GNU/Linux. However, the ZFS on Linux developers have created a "zfs-auto-snapshot" package that you can install from the project's PPA if running Ubuntu. If running another GNU/Linux operating system, you could easily write a Bash or Python script that mimics that functionality, and place it on your root's crontab.

Because both snapshots and clones are cheap, it's recommended that you take advantage of them. Clones can be useful to test deploying virtual machines, or development environments that are cloned from production environments. When finished, they can easily be destroyed, without affecting the parent dataset from which the snapshot was created.

{ 11 } Comments

  1. Ahmed Kamal | July 22, 2013 at 2:51 pm | Permalink

    Worth noting that if you clone a snapshot, that snapshot cannot be deleted afterwards. If you really want to delete it, you can "zfs promote" the clone to a full file-system, and reverse the parent-child relationship, enabling you to delete the origin snapshot

  2. Chris | December 8, 2013 at 9:48 am | Permalink

    one question, just to clarify: assume I create a snapshot, clone it and then write files to the clone. Will these files be written to the snapshot and therefore change the snapshot or will these files be stored at another position. Basically, the question is if cloning a snapshot makes the snapshot writable or if cloning makes a writable snapshot of the snapshot. (in the later the original snapshot should be restored after deleting the clone).

  3. Truxton Fulton | January 17, 2014 at 12:11 am | Permalink

    Thank you Aaron, for these ZFS articles. I have started using ZFS for linux in the last few weeks, and your articles are the most succinct source of information that searching could find. I'm still experimenting with my 12 TB raidz3 pool, but after learning not to use the "sda", "sdb" disk identifiers, I'm rapidly getting comfortable with the idea of trusting my new filesystem. I appreciate you sharing your knowledge.

  4. Steve Yuroff | January 20, 2014 at 12:04 pm | Permalink

    A small correction: you say "However, once the data begins to change, the snapshot will begin storing data."
    No, the production filesystem starts storing data. I know you know this, but as this series is a great benefit to those wrapping their heads around ZFS concepts, this is a point worth clarifying.

    I think this section would also benefit from documenting how the .zfs directory can be used to navigate to a file or folder and duplicating that content vs rolling back the entire filesystem to the snapshot state. I experience needing a file or directory restore from previous version much more often than an entire filesystem.

  5. RvdK | May 13, 2014 at 8:02 am | Permalink

    Wow...this is easily the best explanation of snapshots/clones I've found yet!

  6. Martin Colello | October 22, 2014 at 3:27 pm | Permalink

    If I snap the volume, and then roll back the snap, does that mean all filesystems on that volume are rolled back also?

    Please email me if you know the answer.

  7. Aaron Toponce | December 9, 2014 at 10:52 am | Permalink

    I'm not sure what you mean by "volume". You snapshot datasets. The snapshot then keeps a delta of any deltas after the snapshot. If you rollback the snapshot, then the data on the dataset will be restored to the time you took the snapshot.

  8. HSN | March 30, 2015 at 9:48 am | Permalink

    When you destroy a snapshot you are not actually destroying user data from that snapshot, correct? I mean the most recent data in the dataset will still have all your up-to-the instant changes. If that is true then destroying a snapshot effectively merges that with the previous one in the chain.

  9. Aaron Toponce | April 2, 2015 at 9:48 am | Permalink

    Correct. When destroying the snapshot, you are only destroying the snapshot itself, not the data it points to.

  10. Wade Fitzpatrick | July 12, 2015 at 11:01 pm | Permalink

    It might be worth mentioning that a snapshot is really just a reference to the merkle tree (see the Copy-on-write section) at the point in time that the snapshot was created. Therefore destroying the snapshot is only destroying the reference to the data in the snapshot. It is also the reason why creating and deleting snapshots is instantaneous.

    If you have a file in a dataset, snapshot the dataset then remove the file from the original dataset, you can still access it via the snapshot. The original dataset no longer has a reference to the file but the snapshot does. So when you destroy the dataset, you remove the last remaining reference to it and ZFS can then re-use that space.

  11. Pritchard Musonda | April 25, 2016 at 12:40 pm | Permalink

    Just wanted to say this is the most comprehensive set of tutorials on ZFS for linux available on the internet. Thank you!

{ 6 } Trackbacks

  1. [...] Snapshots and Clones [...]

  2. [...] Snapshots and Clones [...]

  3. [...] Snapshots and Clones [...]

  4. [...] Snapshots and Clones [...]

  5. [...] Snapshots and Clones [...]

  6. [...] Snapshots and Clones [...]

Post a Comment

Your email is never published nor shared.