I went ahead and hacked this script together, so let me elaborate. First, though, a teaser:
$ ./snapspace.sh mainpool/storage SNAPSHOT OLDREFS UNIQUE UNIQUE% zfs-auto-snap_monthly-2011-11-14-18h59 34.67G 11.0G 31% zfs-auto-snap_monthly-2011-12-14-18h59 33.41G 8.95G 26% zfs-auto-snap_monthly-2012-02-09-16h05 123.75G 70.3G 56% ... OLDREFS is how much of the referenced space of the snapshot is not referenced by the current filesystem. UNIQUE is the amount that is referenced by that snapshot and nothing else (the used property), and finally I thought it would be nice to have the unique amount as a percentage of OLDREFS. So, the heart of the script is this: ... fullref=`zfs get -Hp referenced "$1" | awk '{print $3}'` for snap in `zfs list -Hd 1 -t snapshot -o name "$1" | cut -f2- -d@` do snapref=`zfs get -Hp referenced "$1"@"$snap" | awk '{print $3}'` snapwritten=`zfs get -Hp written@"$snap" "$1" | awk '{print $3}'` olddata=$((snapref + snapwritten - fullref)) ... Everything else is sanity checking and display formatting. So, it adds the snapshot referenced data, and the "written@<snap>" value of the filesystem (Richard, thanks again for pointing this out), which would be the size of the current filesystem if nothing was deleted/overwritten (which are equivalent due to copy on write), and subtracts the actual size of the current filesystem, obtaining the amount of data deleted/overwritten since the snapshot was taken (or to put it another way, all the data in that snapshot that isn't in the current filesystem). Since this relies on the written@ property, I think it will only work on illumos-based distros, based on what Richard said (apologies to everyone that doesn't use an illumos kernel, if so). Also, since the values are retrieved with separate commands, if the filesystem is being written to, the numbers may become strange, but probably only for the most recent snapshots. Attaching the full script (renamed to .txt because the listserv hates scripts) for all who are interested. Tim On Fri, Aug 31, 2012 at 8:04 AM, Truhn, Chad <chad.tr...@bowheadsupport.com>wrote: > > > >Is there a way to get the total amount of data referenced by a snapshot > that isn't referenced by a specified snapshot/filesystem? I think this is > what is really desired in order to locate >snapshots with offending space > usage. The written and written@ attributes seem to only do the reverse. > I think you can back calculate it from the snapshot and filesystem > >"referenced" sizes, and the "written@<snap>" property of the filesystem, > but that isn't particularly convenient to do (looks like "zfs get -Hp ..." > makes it possible to hack a script >together for, though). > > > This is what I was hoping to get as well, but I am not sure it's really > possible. Even if you try to calculate the referenced space + displayed > used space and compare against the active filesystem that doesn't really > tell you much because the data on the active filesystem might not be as > static as you want. > > For example: > > If it references 10G and the active filesystem shows 10G used, you might > expect that the snapshot isn't using any space. However, the 10G it > referenced might have been deleted and the 10G in the active filesystem > might be new data and that means your snap could be 10G. But if 9G of that > was on another snapshot, you would have something like this: > > rootpool/export/home@snap.0 - 1G - - > - - > rootpool/export/home@snap.1 - 27K - - > - - > rootpool/export/home@snap.2 - 0 - - > - - > > And the referenced would look something like: > > rootpool/export/home@snap.0 0 - 10G - > rootpool/export/home@snap.1 0 - 9G - > rootpool/export/home@snap.1 0 - 10G - > > And the current filesystem would be: > > rootpool/export/home 40G 20G 10G 10G > 0 0 > > > Then imagine that across more than three snapshots. I can't wrap my head > around logic that would work there. > > I would love if someone could figure out a good way though... > > - Chad > > > > >
#!/bin/bash if (($# < 1)) then echo "usage: $0 <filesystem>" exit 1 fi if [[ $1 == *@* || $1 == /* ]] then echo "Snapshots and paths are not supported" echo "usage: $0 <filesystem>" exit 1 fi echo "SNAPSHOT OLDREFS \tUNIQUE\tUNIQUE%" fullref=`zfs get -Hp referenced "$1" | awk '{print $3}'` for snap in `zfs list -Hd 1 -t snapshot -o name "$1" | cut -f2- -d@` do snapref=`zfs get -Hp referenced "$1"@"$snap" | awk '{print $3}'` snapwritten=`zfs get -Hp written@"$snap" "$1" | awk '{print $3}'` olddata=$((snapref + snapwritten - fullref)) snapused=`zfs get -H used "$1"@"$snap" | awk '{print $3}'` snapusedraw=`zfs get -Hp used "$1"@"$snap" | awk '{print $3}'` suffix="" divisor="1" if ((olddata > 1024)) then suffix="K" divisor="1024" testnum=`echo "$olddata/$divisor" | bc` fi if ((testnum > 1024)) then suffix="M" divisor="(1024*1024)" testnum=`echo "$olddata/$divisor" | bc` fi if ((testnum > 1024)) then suffix="G" divisor="(1024*1024*1024)" testnum=`echo "$olddata/$divisor" | bc` fi if ((testnum > 1024)) then suffix="T" divisor="(1024*1024*1024*1024)" testnum=`echo "$olddata/$divisor" | bc` fi if ((testnum > 1024)) then suffix="P" divisor="(1024*1024*1024*1024*1024)" fi displaydata=`echo "scale = 2; $olddata/$divisor" | bc -l` if ((olddata > 0)) then displaypercent=`echo "100*$snapusedraw/$olddata" | bc` else displaypercent=0 fi chars=`echo "$snap" | wc -m | awk '{print $1}'` spacing="" while ((++chars < 44)) do spacing="$spacing " done echo "$snap $spacing $displaydata$suffix \t$snapused\t$displaypercent%" done
_______________________________________________ zfs-discuss mailing list zfs-discuss@opensolaris.org http://mail.opensolaris.org/mailman/listinfo/zfs-discuss