ZFS-Snapshots vergleichen und große Dateien ausfiltern

Verbrauchen ZFS Snapshots unerwartet viel Speicherplatz, sind oft Änderungen an großen Dateien die Ursache.

E-Mail Clients wie Thunderbird welche sämtliche Nachrichten eines Mailordners in einer großen Datei speichern (mbox-Format) sind eine mögliche Ursache.

Veränderte Dateien identifizieren

Da scheinbar ein entsprechende Funktionalität in ZFS fehlt, wird hier ein kurzes Shell-Skript verwendet um veränderte Dateien zu finden.

# Zu vergleichende Snapshots (ohne Angabe von Dataset und Pfad) nennen
SNAPSHOT1=
SNAPSHOT2=

# In das Snapshot-Verzeichnis des betroffenen Dataset wechseln
DATASET_MOUNTPOINT=/mnt/stash/for/spark/home
cd ${DATASET_MOUNTPOINT}/.zfs/snapshot

# Unterschiede in eine Datei schreiben
LIST_OF_DIFFERING_FILES=`mktemp -t snapdiff`
diff -qr ${SNAPSHOT1} ${SNAPSHOT2} > ${LIST_OF_DIFFERING_FILES}

diff(1)

Große Dateien ausfiltern

Um festzustellen, welche der veränderten Dateien eine bestimmte Größe überschreiten, werden aus dem DIFF die Dateinamen ausgefiltert um dann via find eine Liste auszufiltern.

FIND_FILES_BIGGER_THAN='10M'
SANITIZED_DIFF=`mktemp -t sanitized_diff`

# Unerwünschte Zeilen aus DIFF entfernen
sed 's/^.* and //g' ${LIST_OF_DIFFERING_FILES} | sed 's/ differ$//g' | sed 's/^Only in .*$//g' | sed 's/^File .* is a socket//g' | grep -v '^$' > ${SANITIZED_DIFF}

# Jede Datei aus dem DIFF prüfen
while read line; do
  find $line -type f -size +${FIND_FILES_BIGGER_THAN} -exec ls -ahl {} \;
done < ${SANITIZED_DIFF} 2> /dev/null

sed(1), grep(1), find(1), ls(1)

Bei Überschreitung des festgelegten Schwellwerts laut ${FIND_FILES_BIGGER_THAN} wird die betreffende Datei mittles ls ausgegeben.