What is “Holding a ZFS Snapshot” feature
Remote replication of ZFS datasets can result in different automatic snapshot policies on the two sides of a replication pair. For example, the sending side may want to keep five snapshots at one-minute intervals, whereas the receiving side may want to keep 10 snapshots at one-minute intervals. This can result in the older snapshots being destroyed inadvertently by zfs receive because they no longer exist on the sending side. The ZFS snapshot hold feature addresses this issue. Holding a snapshot (zfs hold) prevents it from being destroyed. If a hold exists on a snapshot, you will not be able to destroy it by using the zfs destroy command. You will look at the two options that you have for destroying a held snapshot in the following examples to come.
In addition, the snapshot hold feature allows a snapshot with clones to be deleted pending the removal of the last clone by using the zfs destroy -d command. You take a closer look at how this is done in subsequent slides.
Each snapshot has an associated user-reference count, which is initialized to zero. This count increases by one whenever there is a hold on the snapshot and decreases by one whenever the hold is released. As discussed, a snapshot can be destroyed only if it has no clones. In the Oracle Solaris 11 release, the snapshot must also have a zero user-reference count before it can be destroyed.
How to hold a ZFS Snapshot
To hold a snapshot or set of snapshots, use the zfs hold keep command followed by the snapshot name. In the example below, a hold tag (keep) is being put on datapool/home/user@snap1.
# zfs hold keep datapool/home/user@snap1
You can use the -r option with the zfs hold command and the keep hold tag to recursively hold the snapshots of all descendent file systems, as shown in the second example. Here, you are holding the snapshots of all the descendant file systems of datapool/home@now.
# zfs hold –r keep datapool/home@now
Display list of held snapshots
You can use the zfs holds command followed by the snapshot name to display a list of held snapshots. In the first example, snapshot holds are being displayed for rpool/export/home@before. Notice that the output returns the name of the snapshot, the tag name (in this case, keep), and the time stamp.
# zfs holds rpool/export/home@before NAME TAG TIMESTAMP rpool/export/home@before keep Sun Jan 14 11:57:45 2018
You can use the -r option with the zfs holds command and the snapshot name to get a recursive list, as illustrated in the second example below.
# zfs holds -r rpool/export/home@before NAME TAG TIMESTAMP rpool/export/home/user@before keep Sun Jan 14 11:59:32 2018 rpool/export/home@before keep Sun Jan 14 11:57:45 2018
Destory or Release a Held ZFS snapshot
As mentioned before, if a hold exists on a snapshot, you will not be able to destroy it by using the zfs destroy command. To destroy the held snapshot, you have two options:
- You can destroy the held snapshot by using the “zfs destroy -d” command followed by the snapshot name, and then release the snapshot hold, which removes the snapshot.
- You can release the snapshot and then destroy it by using the zfs destroy command without the -d option.
To release a hold on a snapshot or set of snapshots, use the zfs release command with the -r option, followed by the hold tag keep and the snapshot name. -r enables a recursive release of the hold and is optional. In the example below, you are releasing the recursive hold on the datapool/home@now snapshot.
# zfs release -r keep datapool/home@now
This snapshot can be destroyed if all the holds have been released.
Snapshot hold properties
The snapshot hold information is identified through two properties:
- The defer_destroy property is on if the snapshot has been marked for deferred destruction by using the “zfs destroy -d” command. Otherwise, the property is off.
- The userrefs property is set to the number of holds on this snapshot, which is also referred to as the user-reference count.
You can view these properties by using the zfs get -r command followed by the comma-separated property name and the file system name.
# zfs get -r defer_destroy,userrefs rpool/export/home NAME PROPERTY VALUE SOURCE rpool/export/home defer_destroy - - rpool/export/home userrefs - - rpool/export/home@before defer_destroy off - rpool/export/home@before userrefs 1 - rpool/export/home@after defer_destroy off - rpool/export/home@after userrefs 0 - rpool/export/home/geek defer_destroy - - rpool/export/home/geek userrefs - - rpool/export/home/geek@today defer_destroy off - rpool/export/home/geek@today userrefs 1 -
In the example in the slide, the defer_destroy and userrefs properties for rpool/export/home are displayed. As you can see from the output, each of the @before snapshots has the defer_destroy property set to off, which is the default, and a value of 1 for the userrefs property, which indicates that each of these snapshots has one hold on it.