SvennD
January 22, 2017

Snapshots in ZFS (ZOL)

Posted on January 22, 2017  •  5 minutes  • 1040 words  •  Suggest Changes

One of the impressive tools in ZOL (ZFS On Linux) is snapshots. Snapshots are a way to make a ‘instant backup’ of the files on the system. The name backup, is not completely correct. If the system dies, the snapshots won’t save you, since snapshots are on the same storage as the data, they don’t eat any unneeded extra space.

A snapshot is the state of the pool/dataset when you created the snapshot. In ZFS snapshots are cheap and fast, so its smart to use the feature to your advantige. The snapshot will remember how the files looked when you create the snapshot, and will only require extra space when changes to those files are made.

How to use

Creating a snapshot :

zfs snapshot [email protected]
zfs snapshot pool/[email protected]

Destroy a snapshot :

zfs destroy [email protected]
zfs destroy pool/[email protected]

**Rename **a snapshot :

zfs rename pool/[email protected] pool/[email protected]_name

**List **snapshots :

zfs list -t snapshot 
zfs list -t snapshot -r pool/dataset

**Rollback **from a snapshot :

zfs rollback pool/[email protected]

note : take care when doing a rollback.

Demo

Lets see this in a simple example. I first created a demo filesystem.__
__

zfs create tank/demo

Lets create a first snapshot on this empty system :

zfs snapshot tank/[email protected]

Getting a list of the current snapshots : _zfs list -t snapshot _There is an option to show snapshots on _zfs list _but thats makes it even more cloudy to work.

# zfs list -t snapshot
NAME                                                USED  AVAIL  REFER  MOUNTPOINT
tank/[email protected]                                      0      -  35.9K  -

Now to generate some data, in ZFS (most COW FS) _fallocate _won’t work. So I use a fancy trick with head but in essence this just generates a file of approx. 10M.

head -c 10M </dev/urandom >data
head -c 10M </dev/urandom >data2
head -c 10M </dev/urandom >data3

Nothing special going on here :

# ls -lh
total 31M
-rw-r--r-- 1 root root 10M Jan 22 19:07 data
-rw-r--r-- 1 root root 10M Jan 22 19:07 data2
-rw-r--r-- 1 root root 10M Jan 22 19:07 data3

# zfs list
NAME                     USED  AVAIL  REFER  MOUNTPOINT
tank                    9.96T  11.1T  3.48G  /tank
tank/demo               30.1M  11.1T  30.0M  /tank/demo

As expected, when you see zfs list there is about 30M in use. Now since this is data that was not in our original (empty) set. The snapshot should not store any changes.

# zfs list -t snapshot
NAME                                                USED  AVAIL  REFER  MOUNTPOINT
tank/[email protected]                                  20.2K      -  35.9K  -

note : the 20.2k are meta-data changes.

Now its time to take a snapshot on the important data we just generated :

# zfs snapshot tank/[email protected]

# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
tank/[email protected] 20.2K - 35.9K -
tank/[email protected] 0 - 30.0M -

Now lets try snapshots, I did a move, a deletion, a overwrite (update) and a new file creation.

mv data data_moved
rm -rf data2
cp data_moved data3
head -c 10M </dev/urandom >data4


# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
tank/[email protected] 20.2K - 35.9K -
tank/[email protected] 20.0M - 30.0M -

Exactly what we expected, the snapshot took a “backup” of data2 and data3 which where removed and overwritten, since data1 was not changed or removed, it does not occupy extra space and data4 is a new file, so it was not there during creation of the snapshot.

Now how do we get the data back ? There are two options, first for small issue’s like accidental removals, you can use the hidden .zfs directory, for larger issue’s you can mount the snapshot on a seperate folder. In every directory on ZFS there is a hidden folder _.zfs. _Note that even ls -la will not pick that directory up.

# ls -ls .zfs/snapshot/
total 1
0 dr-xr-xr-x 1 root root 0 Jan 22 19:25 initial
1 drwxr-xr-x 2 root root 5 Jan 22 19:07 today

# ls -ls .zfs/snapshot/today/
total 30729
10243 -rw-r--r-- 1 root root 10485760 Jan 22 19:07 data
10243 -rw-r--r-- 1 root root 10485760 Jan 22 19:07 data2
10243 -rw-r--r-- 1 root root 10485760 Jan 22 19:07 data3

Voila, there are our data files, prior to removal/overwrite/rename. Note that with this method the snapshot is auto-mounted to /tank/demo/.zfs/snapshot/today as you might have guessed, you can also manually mount snapshots to a location. This can be done in the ’normal’ Linux way :

# mkdir today_snapshot
# mount -t zfs tank/[email protected] today_snapshot

# ls -l today_snapshot/
total 30729
-rw-r--r-- 1 root root 10485760 Jan 22 19:07 data
-rw-r--r-- 1 root root 10485760 Jan 22 19:07 data2
-rw-r--r-- 1 root root 10485760 Jan 22 19:07 data3

To unmount just use umount

umount tank/[email protected]

Our snapshot name was not chosen very long-term minded, you can rename them to something more verbose :

zfs rename tank/[email protected] tank/[email protected]

The last thing we want to do, is remove a snapshot, lets remove the initial snapshot, since there was no data :

zfs destroy tank/[email protected]

There is another option, which I don’t trust much beside this example and I would only advice it to use with extreme care. Rollback, can be done straight back to a state of the system at the time of the snapshot creation, however only back to the latest snapshot. If you want to go back further, you need to destroy the snapshots in between.

zfs rollback -r tank/[email protected]

Note the -r will destroy any snapshots between current state and @22jan2017 snapshot.

Relevant

 

Support

If you enjoyed this website, consider buying me a Dr. Pepper

Buy me a Dr PepperBuy me a Dr Pepper