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 NAME PROPERTY VALUE SOURCE 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: datapool/project1@tuesday 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 NAME USED AVAIL REFER MOUNTPOINT 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 NAME PROPERTY VALUE SOURCE 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 NAME AVAIL USED USEDSNAP USEDDS USEDREFRESERV USEDCHILD 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:
Find this useful! spread the word, share your knowledge