Understanding “Holding a ZFS Snapshot” Feature

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

Note: Each snapshot has its own tag namespace, and tags must be unique within that space. In this example, keep is a user-defined tag.

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.

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.

Note: If a held snapshot has associated clones, you must destroy the clones first before you can destroy the held snapshot.

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.

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.