Understanding ZFS Snapshot – Tutorial

Oracle Solaris 0 Comments

ZFS file system offer many feature that can help us during our day to day administration tasks, one of this feature is the zfs snapshot which can be used for backup purpose including full and incremental backup or rolling back a system to a previous state.
ZFS snapshot can be created quickly and they consume nothing, they only reference data stored on the source file system and as you change it, snapshot size grow.
let’s deep dive into this with some examples.

Creating a ZFS Snapshot

Let’s start by creating a ZFS filesystem and then use the zfs snapshot command to create our snapshot, you should also note that the snapshot name should contain the ‘@’ sign, for example to create a snapshot for the datapool/project1 we can use the following command:

root@sol01:~# zfs create datapool/project1
root@sol01:~# zfs snapshot datapool/project1@today

Listing ZFS Snapshot

We can list the snapshot related to a file system (dataset) using the following command:

root@sol01:~# zfs list -t snapshot
NAME                            USED  AVAIL  REFER  MOUNTPOINT
datapool/project1@today            0      -    31K  -
rpool/ROOT/solaris@install      112M      -  3.96G  -
rpool/ROOT/solaris/var@install  152M      -   389M  -
rpool/newhome/david@snap1        20K      -  5.04M  -
rpool/newhome/david@snap2        20K      -  10.0M  -

Each snapshot is stored in local hidden directory which can be controlled using the snapdir property

root@sol01:~# ls -lha /datapool/project1/
total 6
drwxr-xr-x 2 root root 2 Jan 12 10:13 .
drwxr-xr-x 3 root root 3 Jan 12 10:13 ..
root@sol01:~# zfs get snapdir datapool/project1
datapool/project1 snapdir hidden default
root@sol01:~# zfs set snapdir=visible datapool/project1
root@sol01:~# ls -la /datapool/project1/
total 6
drwxr-xr-x 3 root root 2 Jan 12 10:13 .
drwxr-xr-x 3 root root 3 Jan 12 10:13 ..
dr-xr-xr-x 4 root root 4 Jan 12 10:13 .zfs
root@sol01:~# cd data/datapool/project1/.zfs/snapshot/
root@sol01:/datapool/project1/.zfs/snapshot# ls -l
total 3
drwxr-xr-x 2 root root 2 Jan 12 10:13 today

Her our snapshot named today is visible in the listing.
We have created our file system and it’s snapshot, let’s see how we can use the zfs snapshot feature to restore a deleted file.

Rolling Back a ZFS snapshot

Rolling back a zfs snapshot will discard all change to the file system and will revert it state since a specific snapshot, we will delete the file projectplan and see how we can restore it using our snapshot named tuesday.

root@sol01:/datapool/project1# zfs snapshot datapool/project1@monday
root@sol01:/datapool/project1# mkfile 1m projectplan
root@sol01:/datapool/project1# mkfile 1m meeting
root@sol01:/datapool/project1# ls -lh
total 2054
-rw------T 1 root root 1.0M Jan 12 10:24 meeting
-rw------T 1 root root 1.0M Jan 12 10:24 projectplan
root@sol01:/datapool/project1# zfs snapshot datapool/project1@tuesday
root@sol01:/datapool/project1# rm projectplan
root@sol01:/datapool/project1# ls -l
total 2053
-rw------T 1 root root 1048576 Jan 12 10:24 meeting
root@sol01:/datapool/project1# zfs rollback datapool/project1@monday
cannot rollback to 'datapool/project1@monday': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
root@sol01:/datapool/project1# zfs rollback datapool/project1@tuesday
root@sol01:/datapool/project1# ls
meeting projectplan

As you can see, zfs will only let you rollback to the most recent snapshot, if you need to use the older datapool/project1@monday we need to use the -r option for zfs rollback command.

ZFS Snapshot Space Usage

When we create a snapshot it’s empty and contain no data, it’s content will be based on the change done on the source file system, in other word it will only contain the difference between the two, this can be seen on the USED property with the following zfs command:

root@sol01:/datapool/project1# zfs list -r -t snapshot datapool/project1
datapool/project1@monday 1K - 2.03M -

If we want the zfs list to show snapshot in the listing without specifying the -t snapshot we must modify the listsnaps property on the zfs pool :

root@sol01:/datapool/project1# zpool get listsnap datapools datapool
datapool listsnapshots off default
root@sol01:/datapool/project1# zpool set listsnaps=on datapool
root@sol01:/datapool/project1# zfs list -r datapool/project1
NAME                       USED  AVAIL  REFER  MOUNTPOINT
datapool/project1         2.04M   153M  2.03M  /datapool/project1
datapool/project1@monday     1K      -  2.03M  -

Her we can see that the file system datapool/project1 is ~2MB in size and the snapshot datapool/project1@monday is only 1K, the REFER property is the initial size of the snapshot when it was created which the same size the the dataset. When we start modifying data on datapool/project1 we will see that the value of the USED property of the snapshot increase.

let’s move to a more detailed output, we can use zfs list -r -o space to have the following:

root@sol01:/datapool/project1# du -sh .
 5.4M .
root@sol01:/datapool/project1# ls -lh
total 6927
-r--r--r-- 1 root root 1.7M Jan 12 11:17 lastlog
-rw------T 1 root root 1.0M Jan 12 10:24 meeting
-rw-r--r-- 1 root root 545K Jan 12 11:17 messages
root@sol01:/datapool/project1# zfs list -r -o space datapool/project1
datapool/project1          150M  4.43M     1.02M   3.41M              0          0
datapool/project1@monday      -  1.02M         -       -              -          -

It’s more clear now, for datapool/project1 , the USED property is the size of all file including snapshot, USEDDS is the size of all the file on the current directory, USEDSNAP is the size of the snapshot so USEDSNAP + USEDDS = USED.
The USED property for datapool/project1@monday is the size of the snapshot and the two other USEDREFRESERV and USEDCHILD are the amount of space used by zfs reservation and space used my dataset children respectively.

Destroying a ZFS snapshot

To remove a snapshot , use the zfs destroy command. Please note that we can’t remove a snapshot if there is any clone related to it.

root@sol01:/datapool/project1# zfs destroy datapool/project1@monday

Backup and restore a ZFS File System Using Snapshot

Using the zfs send and zfs receive we can perform full and incremental backup of a dataset and we can also use output redirection to store the backup in gzip format, a tape, a disk or in a remote file system.

Backing up a dataset to gzip file

root@sol01:/datapool/project1# zfs send datapool/project1@monday | gzip -9 > projet1.gz

To a remote system

zfs send datapool/project1@monday | ssh sol02 zfs recv testpool/project1

To a tape drive

zfs send datapool/project1@monday > /dev/rmt/0

ZFS snapshot replication

For every snapshot taken we can send incremental update to a local filesystem or to a remote host, this is useful for bandwidth optimization and time management.

let’s perform a simple full and then an incremental replication.


root@sol01:~# zfs send datapool/project1@monday | zfs receive -Fv rpool/project1
receiving full stream of datapool/project1@monday into rpool/project1@monday
received 47.6KB stream in 2 seconds (23.8KB/sec)


root@sol01:~# zfs send -I datapool/project1@monday datapool/project1@tuesdayIncr | zfs receive -Fv rpool/project1
receiving incremental stream of datapool/project1@mondayIncr into rpool/project1@mondayIncr
received 312B stream in 3 seconds (104B/sec)
receiving incremental stream of datapool/project1@tuesdayIncr into rpool/project1@tuesdayIncr
received 312B stream in 2 seconds (156B/sec)

This is useful where there is a file system with many snapshot, we can perform an incremental send that take all the snapshot between the first one and the last one to perform an incremental replication.

The  -R and -I perform a recursive and incremental send respectively or if we prefer a more granular way we can use the -D switch to perform a deduplication before sending the zfs data stream. The same process can be used to send this replication to a remote system just pipe the output of the zfs send command to an ssh session.

Identifying the difference between two snapshots

This can easily be done using the zfs diff command.
Using our last example, we can see what have changed:

root@sol01:~# zfs diff datapool/project1@monday datapool/project1@tuesdayIncr
M /datapool/project1/
+ /datapool/project1/projectplan
- /datapool/project1/messages

Files prefixed with the + sign are the one we added and those prefixed with the – sign are the one that was removed.

As per Oracle Solaris documentation the identifier are the following:

zfs snapshot difference identifier


Find this useful! spread the word, share your knowledge

1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 5.00 out of 5)

Leave a Reply

Your email address will not be published. Required fields are marked *