Das zfs
-Werkzeug ist dafür
verantwortlich, alle ZFS Datasets innerhalb
eines Pools zu erstellen, zerstören und zu verwalten. Der Pool
selbst wird durch zpool
verwaltet.
Anders als in traditionellen Festplatten- und
Volumenmanagern wird der Plattenplatz in
ZFS nicht
vorher allokiert. Bei traditionellen Dateisystemen gibt es,
nachdem der Plattenplatz partitioniert und
zugeteilt wurde, keine Möglichkeit, ein zusätzliches
Dateisystem hinzuzufügen, ohne eine neue Platte
anzuschließen. Mit
ZFS lassen sich neue Dateisysteme zu jeder
Zeit anlegen. Jedes Dataset
besitzt Eigenschaften wie Komprimierung, Deduplizierung,
Zwischenspeicher (caching), Quotas, genauso wie andere
nützliche Einstellungen wie Schreibschutz, Unterscheidung
zwischen Groß- und Kleinschreibung, Netzwerkfreigaben und
einen Einhängepunkt. Datasets können ineinander verschachtelt
werden und Kind-Datasets erben die Eigenschaften ihrer Eltern.
Jedes Dataset kann als eine Einheit verwaltet,
delegiert,
repliziert,
mit Schnappschüssen
versehen, in Jails
gesteckt und zerstört werden. Es gibt viele Vorteile,
ein separates Dataset für jede Art von Dateien anzulegen. Der
einzige Nachteil einer großen Menge an Datasets ist, dass
manche Befehle wie zfs list
langsamer sind
und dass das Einhängen von hunderten oder hunderttausenden von
Datasets den FreeBSD-Bootvorgang verzögert.
Erstellen eines neuen Datasets und aktivieren von LZ4 Komprimierung:
#
zfs list
NAME USED AVAIL REFER MOUNTPOINT mypool 781M 93.2G 144K none mypool/ROOT 777M 93.2G 144K none mypool/ROOT/default 777M 93.2G 777M / mypool/tmp 176K 93.2G 176K /tmp mypool/usr 616K 93.2G 144K /usr mypool/usr/home 184K 93.2G 184K /usr/home mypool/usr/ports 144K 93.2G 144K /usr/ports mypool/usr/src 144K 93.2G 144K /usr/src mypool/var 1.20M 93.2G 608K /var mypool/var/crash 148K 93.2G 148K /var/crash mypool/var/log 178K 93.2G 178K /var/log mypool/var/mail 144K 93.2G 144K /var/mail mypool/var/tmp 152K 93.2G 152K /var/tmp#
zfs create -o compress=lz4
mypool/usr/mydataset
#
zfs list
NAME USED AVAIL REFER MOUNTPOINT mypool 781M 93.2G 144K none mypool/ROOT 777M 93.2G 144K none mypool/ROOT/default 777M 93.2G 777M / mypool/tmp 176K 93.2G 176K /tmp mypool/usr 704K 93.2G 144K /usr mypool/usr/home 184K 93.2G 184K /usr/home mypool/usr/mydataset 87.5K 93.2G 87.5K /usr/mydataset mypool/usr/ports 144K 93.2G 144K /usr/ports mypool/usr/src 144K 93.2G 144K /usr/src mypool/var 1.20M 93.2G 610K /var mypool/var/crash 148K 93.2G 148K /var/crash mypool/var/log 178K 93.2G 178K /var/log mypool/var/mail 144K 93.2G 144K /var/mail mypool/var/tmp 152K 93.2G 152K /var/tmp
Ein Dataset zu zerstören ist viel schneller, als alle Dateien zu löschen, die sich in dem Dataset befindet, da es keinen Scan aller Dateien und aktualisieren der dazugehörigen Metadaten erfordert.
Zerstören des zuvor angelegten Datasets:
#
zfs list
NAME USED AVAIL REFER MOUNTPOINT mypool 880M 93.1G 144K none mypool/ROOT 777M 93.1G 144K none mypool/ROOT/default 777M 93.1G 777M / mypool/tmp 176K 93.1G 176K /tmp mypool/usr 101M 93.1G 144K /usr mypool/usr/home 184K 93.1G 184K /usr/home mypool/usr/mydataset 100M 93.1G 100M /usr/mydataset mypool/usr/ports 144K 93.1G 144K /usr/ports mypool/usr/src 144K 93.1G 144K /usr/src mypool/var 1.20M 93.1G 610K /var mypool/var/crash 148K 93.1G 148K /var/crash mypool/var/log 178K 93.1G 178K /var/log mypool/var/mail 144K 93.1G 144K /var/mail mypool/var/tmp 152K 93.1G 152K /var/tmp#
zfs destroy
mypool/usr/mydataset
#
zfs list
NAME USED AVAIL REFER MOUNTPOINT mypool 781M 93.2G 144K none mypool/ROOT 777M 93.2G 144K none mypool/ROOT/default 777M 93.2G 777M / mypool/tmp 176K 93.2G 176K /tmp mypool/usr 616K 93.2G 144K /usr mypool/usr/home 184K 93.2G 184K /usr/home mypool/usr/ports 144K 93.2G 144K /usr/ports mypool/usr/src 144K 93.2G 144K /usr/src mypool/var 1.21M 93.2G 612K /var mypool/var/crash 148K 93.2G 148K /var/crash mypool/var/log 178K 93.2G 178K /var/log mypool/var/mail 144K 93.2G 144K /var/mail mypool/var/tmp 152K 93.2G 152K /var/tmp
In modernen Versionen von ZFS ist
zfs destroy
asynchron und der freie
Speicherplatz kann erst nach ein paar Minuten im Pool
auftauchen. Verwenden Sie zpool get freeing
, um die
Eigenschaft poolname
freeing
aufzulisten, die
angibt, bei wievielen Datasets die Blöcke im Hintergrund
freigegeben werden. Sollte es Kind-Datasets geben,
Schnappschüsse oder
andere Datasets, dann lässt sich der Elternknoten nicht
zerstören. Um ein Dataset und all seine Kinder zu zerstören,
verwenden Sie die Option -r
, um das Dataset
und all seine Kinder rekursiv zu entfernen. Benutzen Sie die
Option -n
und -v
, um
Datasets und Snapshots anzuzeigen, die durch diese Aktion
zerstört werden würden, dies jedoch nur zu simulieren und
nicht wirklich durchzuführen. Speicherplatz, der dadurch
freigegeben würde, wird ebenfalls angezeigt.
Ein Volume ist ein spezieller Typ von Dataset. Anstatt
dass es als Dateisystem eingehängt wird, stellt es ein
Block-Gerät unter
/dev/zvol/
dar. Dies erlaubt es, das Volume für andere Dateisysteme zu
verwenden, die Festplatten einer virtuellen Maschine
bereitzustellen oder über Protokolle wie
iSCSI oder HAST
exportiert zu werden.poolname
/dataset
Ein Volume kann mit einem beliebigen Dateisystem formatiert werden oder auch ohne ein Dateisystem als reiner Datenspeicher fungieren. Für den Benutzer erscheint ein Volume als eine gewöhnliche Platte. Indem gewöhnliche Dateisysteme auf diesen zvols angelegt werden, ist es möglich, diese mit Eigenschaften auszustatten, welche diese normalerweise nicht besitzen. Beispielsweise wird durch Verwendung der Komprimierungseigenschaft auf einem 250 MB Volume das Erstellen eines komprimierten FAT Dateisystems möglich.
#
zfs create -V 250m -o compression=on tank/fat32
#
zfs list tank
NAME USED AVAIL REFER MOUNTPOINT tank 258M 670M 31K /tank#
newfs_msdos -F32 /dev/zvol/tank/fat32
#
mount -t msdosfs /dev/zvol/tank/fat32 /mnt
#
df -h /mnt | grep fat32
Filesystem Size Used Avail Capacity Mounted on /dev/zvol/tank/fat32 249M 24k 249M 0% /mnt#
mount | grep fat32
/dev/zvol/tank/fat32 on /mnt (msdosfs, local)
Ein Volume zu zerstören ist sehr ähnlich wie ein herkömmliches Dataset zu entfernen. Die Operation wird beinahe sofort durchgeführt, jedoch kann es mehrere Minuten dauern, bis der freie Speicherplatz im Hintergrund wieder freigegeben ist.
Der Name eines Datasets lässt sich durch
zfs rename
ändern. Das Eltern-Dataset kann
ebenfalls mit diesem Kommando umbenannt werden. Ein Dataset
unter einem anderen Elternteil umzubenennen wird den Wert
dieser Eigenschaft verändern, die vom Elternteil vererbt
wurden. Wird ein Dataset umbenannt, wird es abgehängt und
dann erneut unter der neuen Stelle eingehängt (welche vom
neuen Elternteil geerbt wird). Dieses Verhalten kann durch
die Option -u
verhindert werden.
Ein Dataset umbenennen und unter einem anderen Elterndataset verschieben:
#
zfs list
NAME USED AVAIL REFER MOUNTPOINT mypool 780M 93.2G 144K none mypool/ROOT 777M 93.2G 144K none mypool/ROOT/default 777M 93.2G 777M / mypool/tmp 176K 93.2G 176K /tmp mypool/usr 704K 93.2G 144K /usr mypool/usr/home 184K 93.2G 184K /usr/home mypool/usr/mydataset 87.5K 93.2G 87.5K /usr/mydataset mypool/usr/ports 144K 93.2G 144K /usr/ports mypool/usr/src 144K 93.2G 144K /usr/src mypool/var 1.21M 93.2G 614K /var mypool/var/crash 148K 93.2G 148K /var/crash mypool/var/log 178K 93.2G 178K /var/log mypool/var/mail 144K 93.2G 144K /var/mail mypool/var/tmp 152K 93.2G 152K /var/tmp#
zfs rename
mypool/usr/mydataset
mypool/var/newname
#
zfs list
NAME USED AVAIL REFER MOUNTPOINT mypool 780M 93.2G 144K none mypool/ROOT 777M 93.2G 144K none mypool/ROOT/default 777M 93.2G 777M / mypool/tmp 176K 93.2G 176K /tmp mypool/usr 616K 93.2G 144K /usr mypool/usr/home 184K 93.2G 184K /usr/home mypool/usr/ports 144K 93.2G 144K /usr/ports mypool/usr/src 144K 93.2G 144K /usr/src mypool/var 1.29M 93.2G 614K /var mypool/var/crash 148K 93.2G 148K /var/crash mypool/var/log 178K 93.2G 178K /var/log mypool/var/mail 144K 93.2G 144K /var/mail mypool/var/newname 87.5K 93.2G 87.5K /var/newname mypool/var/tmp 152K 93.2G 152K /var/tmp
Schnappschüsse können auf diese Weise ebenfalls umbenannt
werden. Aufgrund der Art von Schnappschüssen können diese
nicht unter einem anderen Elterndataset eingehängt werden. Um
einen rekursiven Schnappschuss umzubenennen, geben Sie die
Option -r
an, um alle Schnappschüsse mit dem
gleichen Namen im Kind-Dataset ebenfalls umzubenennen.
#
zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT mypool/var/newname@first_snapshot 0 - 87.5K -#
zfs rename
mypool/var/newname@first_snapshot
new_snapshot_name
#
zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT mypool/var/newname@new_snapshot_name 0 - 87.5K -
Jedes ZFS-Dataset besitzt eine Menge
von Eigenschaften, die sein Verhalten beeinflussen. Die
meisten Eigenschaften werden automatisch vom Eltern-Dataset
vererbt, können jedoch lokal überschrieben werden. Sie legen
eine Eigenschaft durch zfs set
fest. Die
meisten Eigenschaften haben eine begrenzte Menge von gültigen
Werten. property
=value
dataset
zfs get
stellt diese dar und zeigt
jede mögliche Eigenschaft und gültige Werte an. Die meisten
Eigenschaften können über zfs inherit
wieder auf ihren Ausgangswert zurückgesetzt werden.
Benutzerdefinierte Eigenschaften lassen sich ebenfalls
setzen. Diese werden Teil der Konfiguration des Datasets und
können dazu verwendet werden, zusätzliche Informationen über
das Dataset oder seine Bestandteile zu speichern. Um diese
benutzerdefinierten Eigenschaften von den
ZFS-eigenen zu unterscheiden, wird ein
Doppelpunkt (:
) verwendet, um einen eigenen
Namensraum für diese Eigenschaft zu erstellen.
#
zfs set
custom
:costcenter
=1234
tank
#
zfs get
NAME PROPERTY VALUE SOURCE tank custom:costcenter 1234 localcustom
:costcenter
tank
Um eine selbstdefinierte Eigenschaft umzubenennen,
verwenden Sie zfs inherit
mit der Option
-r
. Wenn die benutzerdefinierte Eigenschaft
nicht in einem der Eltern-Datasets definiert ist, wird diese
komplett entfernt (obwohl diese Änderungen natürlich in der
Historie des Pools noch aufgezeichnet sind).
#
zfs inherit -r
custom
:costcenter
tank
#
zfs get
NAME PROPERTY VALUE SOURCE tank custom:costcenter - -custom
:costcenter
tank
#
zfs get all
tank
| grepcustom
:costcenter
#
Zwei häufig verwendete und nützliche Dataset-Eigenschaften sind die Freigabeoptionen von NFS und SMB. Diese Optionen legen fest, ob und wie ZFS-Datasets im Netzwerk freigegeben werden. Derzeit unterstützt FreeBSD nur Freigaben von Datasets über NFS. Um den Status einer Freigabe zu erhalten, geben Sie folgendes ein:
#
zfs get sharenfs
NAME PROPERTY VALUE SOURCE mypool/usr/home sharenfs on localmypool/usr/home
#
zfs get sharesmb
NAME PROPERTY VALUE SOURCE mypool/usr/home sharesmb off localmypool/usr/home
Um ein Dataset freizugeben, geben Sie ein:
#
zfs set sharenfs=on
mypool/usr/home
Es ist auch möglich, weitere Optionen für die
Verwendung von Datasets über NFS
zu definieren, wie etwa -alldirs
,
-maproot
und -network
.
Um zusätzliche Optionen auf ein durch
NFS freigegebenes Dataset festzulegen,
geben Sie ein:
#
zfs set sharenfs="-alldirs,maproot=
root
,-network=192.168.1.0/24
"mypool/usr/home
Schnappschüsse
sind eine der mächtigen Eigenschaften von
ZFS. Ein Schnappschuss bietet einen
nur-Lese Zustand eines Datasets zu einem bestimmten Zeitpunkt.
Mit Kopieren-beim-Schreiben (Copy-On-Write
COW), können Schnappschüsse schnell
erstellt werden durch das Aufheben der älteren Version der
Daten auf der Platte. Falls kein Snapshot existiert, wird der
Speicherplatz wieder für zukünftige Verwendung freigegeben
wenn Daten geschrieben oder gelöscht werden. Schnappschüsse
sparen Speicherplatz, indem diese nur die Unterschiede
zwischen dem momentanen Dataset und der vorherigen Version
aufzeichnen. Schnappschüsse sind nur auf ganzen Datasets
erlaubt, nicht auf individuellen Dateien oder Verzeichnissen.
Wenn ein Schnappschuss eines Datasets erstellt wird, wird
alles was darin enthalten ist, dupliziert. Das beinhaltet
Dateisystemeigenschaften, Dateien, Verzeichnisse, Rechte und
so weiter. Schnappschüsse benötigen keinen zusätzlichen
Speicherplatz wenn diese erstmals angelegt werden, nur wenn
Blöcke, die diese referenzieren, geändert werden. Rekursive
Schnappschüsse, die mit der Option -r
erstellt, erzeugen einen mit dem gleichen Namen des Datasets
und all seinen Kindern, was eine konsistente Momentaufnahme
aller Dateisysteme darstellt. Dies kann wichtig sein, wenn
eine Anwendung Dateien auf mehreren Datasets ablegt, die
miteinander in Verbindung stehen oder voneinander abhängig
sind. Ohne Schnappschüsse würde ein Backup Kopien dieser
Dateien zu unterschiedlichen Zeitpunkten enthalten.
Schnappschüsse in ZFS bieten eine Vielzahl von Eigenschaften, die selbst in anderen Dateisystemen mit Schnappschussfunktion nicht vorhanden sind. Ein typisches Beispiel zur Verwendung von Schnappschüssen ist, den momentanen Stand des Dateisystems zu sichern, wenn eine riskante Aktion wie das Installieren von Software oder eine Systemaktualisierung durchgeführt wird. Wenn diese Aktion fehlschlägt, so kann der Schnappschuss zurückgerollt werden und das System befindet sich wieder in dem gleichen Zustand, wie zu dem, als der Schnappschuss erstellt wurde. Wenn die Aktualisierung jedoch erfolgreich war, kann der Schnappschuss gelöscht werden, um Speicherplatz frei zu geben. Ohne Schnappschüsse, wird durch ein fehlgeschlagenes Update eine Wiederherstellung der Sicherung fällig, was oft mühsam und zeitaufwändig ist, außerdem ist währenddessen das System nicht verwendbar. Schnappschüsse lassen sich schnell und mit wenig bis gar keiner Ausfallzeit zurückrollen, selbst wenn das System im normalen Betrieb läuft. Die Zeitersparnis ist enorm, wenn mehrere Terabyte große Speichersysteme eingesetzt werden und viel Zeit für das Kopieren der Daten vom Sicherungssystem benötigt wird. Schnappschüsse sind jedoch keine Ersatz für eine Vollsicherung des Pools, können jedoch als eine schnelle und einfache Sicherungsmethode verwendet werden, um eine Kopie eines Datasets zu einem bestimmten Zeitpunkt zu sichern.
Schnappschüsse werden durch das Kommando
zfs snapshot
angelegt. Durch Angabe der Option dataset
@snapshotname
-r
werden Schnappschüsse rekursive angelegt, mit dem gleichen
Namen auf allen Datasets.
Einen rekursiven Schnappschuss des gesamten Pools erzeugen:
#
zfs list -t all
NAME USED AVAIL REFER MOUNTPOINT mypool 780M 93.2G 144K none mypool/ROOT 777M 93.2G 144K none mypool/ROOT/default 777M 93.2G 777M / mypool/tmp 176K 93.2G 176K /tmp mypool/usr 616K 93.2G 144K /usr mypool/usr/home 184K 93.2G 184K /usr/home mypool/usr/ports 144K 93.2G 144K /usr/ports mypool/usr/src 144K 93.2G 144K /usr/src mypool/var 1.29M 93.2G 616K /var mypool/var/crash 148K 93.2G 148K /var/crash mypool/var/log 178K 93.2G 178K /var/log mypool/var/mail 144K 93.2G 144K /var/mail mypool/var/newname 87.5K 93.2G 87.5K /var/newname mypool/var/newname@new_snapshot_name 0 - 87.5K - mypool/var/tmp 152K 93.2G 152K /var/tmp#
zfs snapshot -r
mypool@my_recursive_snapshot
#
zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT mypool@my_recursive_snapshot 0 - 144K - mypool/ROOT@my_recursive_snapshot 0 - 144K - mypool/ROOT/default@my_recursive_snapshot 0 - 777M - mypool/tmp@my_recursive_snapshot 0 - 176K - mypool/usr@my_recursive_snapshot 0 - 144K - mypool/usr/home@my_recursive_snapshot 0 - 184K - mypool/usr/ports@my_recursive_snapshot 0 - 144K - mypool/usr/src@my_recursive_snapshot 0 - 144K - mypool/var@my_recursive_snapshot 0 - 616K - mypool/var/crash@my_recursive_snapshot 0 - 148K - mypool/var/log@my_recursive_snapshot 0 - 178K - mypool/var/mail@my_recursive_snapshot 0 - 144K - mypool/var/newname@new_snapshot_name 0 - 87.5K - mypool/var/newname@my_recursive_snapshot 0 - 87.5K - mypool/var/tmp@my_recursive_snapshot 0 - 152K -
Schnappschüsse werden nicht durch einen
zfs list
-Befehl angezeigt. Um
Schnappschüsse mit aufzulisten, muss
-t snapshot
an das Kommando
zfs list
angehängt werden. Durch
-t all
werden sowohl Dateisysteme als auch
Schnappschüsse nebeneinander angezeigt.
Schnappschüsse werden nicht direkt eingehängt, deshalb
wird auch kein Pfad in der Spalte
MOUNTPOINT
angezeigt. Ebenso wird kein
freier Speicherplatz in der Spalte AVAIL
aufgelistet, da Schnappschüsse nicht mehr geschrieben werden
können, nachdem diese angelegt wurden. Vergleichen Sie den
Schnappschuss mit dem ursprünglichen Dataset von dem es
abstammt:
#
zfs list -rt all
NAME USED AVAIL REFER MOUNTPOINT mypool/usr/home 184K 93.2G 184K /usr/home mypool/usr/home@my_recursive_snapshot 0 - 184K -mypool/usr/home
Durch das Darstellen des Datasets und des Schnappschusses nebeneinander zeigt deutlich, wie Schnappschüsse in COW Manier funktionieren. Sie zeichnen nur die Änderungen (delta) auf, die währenddessen entstanden sind und nicht noch einmal den gesamten Inhalt des Dateisystems. Das bedeutet, dass Schnappschüsse nur wenig Speicherplatz benötigen, wenn nur kleine Änderungen vorgenommen werden. Der Speicherverbrauch kann sogar noch deutlicher gemacht werden, wenn eine Datei auf das Dataset kopiert wird und anschließend ein zweiter Schnappschuss angelegt wird:
#
cp
/etc/passwd
/var/tmp
#
zfs snapshot
mypool/var/tmp
@after_cp
#
zfs list -rt all
NAME USED AVAIL REFER MOUNTPOINT mypool/var/tmp 206K 93.2G 118K /var/tmp mypool/var/tmp@my_recursive_snapshot 88K - 152K - mypool/var/tmp@after_cp 0 - 118K -mypool/var/tmp
Der zweite Schnappschuss enthält nur die Änderungen am
Dataset, die nach der Kopieraktion gemacht wurden. Dies
bedeutet enorme Einsparungen von Speicherplatz. Beachten
Sie, dass sich die Größe des Schnappschusses
mypool/var/tmp@my_recursive_snapshot
in der Spalte USED
ebenfalls
geändert hat, um die Änderungen von sich selbst und dem
Schnappschuss, der im Anschluss angelegt wurde,
anzuzeigen.
ZFS enthält ein eingebautes Kommando, um die
Unterschiede zwischen zwei Schnappschüssen miteinander zu
vergleichen. Das ist hilfreich, wenn viele Schnappschüsse
über längere Zeit angelegt wurden und der Benutzer sehen
will, wie sich das Dateisystem über diesen Zeitraum
verändert hat. Beispielsweise kann
zfs diff
den letzten Schnappschuss
finden, der noch eine Datei enthält, die aus Versehen
gelöscht wurde. Wenn dies für die letzten beiden
Schnappschüsse aus dem vorherigen Abschnitt durchgeführt
wird, ergibt sich folgende Ausgabe:
#
zfs list -rt all
NAME USED AVAIL REFER MOUNTPOINT mypool/var/tmp 206K 93.2G 118K /var/tmp mypool/var/tmp@my_recursive_snapshot 88K - 152K - mypool/var/tmp@after_cp 0 - 118K -mypool/var/tmp
#
zfs diff
M /var/tmp/ + /var/tmp/passwdmypool/var/tmp@my_recursive_snapshot
Das Kommando zeigt alle Änderungen zwischen dem
angegebenen Schnappschuss (in diesem Fall
)
und dem momentan aktuellen Dateisystem. Die erste Spalte
zeigt die Art der Änderung an:mypool/var/tmp@my_recursive_snapshot
+ | Das Verzeichnis oder die Datei wurde hinzugefügt. |
- | Das Verzeichnis oder die Datei wurde gelöscht. |
M | Das Verzeichnis oder die Datei wurde geändert. |
R | Das Verzeichnis oder die Datei wurde umbenannt. |
Vergleicht man die Ausgabe mit der Tabelle, wird klar,
dass
hinzugefügt wurde, nachdem der Schnappschuss
passwd
erstellt wurde. Das resultierte ebenfalls in einer Änderung
am darüberliegenden Verzeichnis, das unter
mypool/var/tmp@my_recursive_snapshot
eingehängt ist./var/tmp
Zwei Schnappschüsse zu vergleichen ist hilfreich, wenn die Replikationseigenschaft von ZFS verwendet wird, um ein Dataset auf einen anderen Host zu Sicherungszwecken übertragen.
Zwei Schnappschüsse durch die Angabe des kompletten Namens des Datasets und dem Namen des Schnappschusses beider Datasets vergleichen:
#
cp /var/tmp/passwd /var/tmp/passwd.copy
#
zfs snapshot
mypool/var/tmp@diff_snapshot
#
zfs diff
M /var/tmp/ + /var/tmp/passwd + /var/tmp/passwd.copymypool/var/tmp@my_recursive_snapshot
mypool/var/tmp@diff_snapshot
#
zfs diff
M /var/tmp/ + /var/tmp/passwdmypool/var/tmp@my_recursive_snapshot
mypool/var/tmp@after_cp
Ein Administrator, der für die Sicherung zuständig ist, kann zwei Schnappschüsse miteinander vergleichen, die vom sendenden Host empfangen wurden, um festzustellen, welche Änderungen am Dataset vorgenommen wurden. Lesen Sie dazu den Abschnitt Replication um weitere Informationen zu erhalten.
Wenn zumindest ein Schnappschuss vorhanden ist, kann
dieser zu einem beliebigen Zeitpunkt zurückgerollt werden.
In den meisten Fällen passiert dies, wenn der aktuelle
Zustand des Datasets nicht mehr benötigt wird und eine
ältere Version bevorzugt wird. Szenarien wie lokale
Entwicklungstests, die fehlgeschlagen sind, defekte
Systemaktualisierungen, welche die Funktionalität des
Gesamtsystems einschränken oder die Anforderung,
versehentlich gelöschte Dateien oder Verzeichnisse
wiederherzustellen, sind allgegenwärtig. Glücklicherweise
ist das zurückrollen eines Schnappschusses so leicht wie die
Eingabe von
zfs rollback
.
Abhängig davon, wie viele Änderungen betroffen sind, wird
diese Operation innerhalb einer gewissen Zeit abgeschlossen
sein. Während dieser Zeit bleibt das Dataset in einem
konsistenten Zustand, sehr ähnlich den ACID-Prinzipien, die
eine Datenbank beim Zurückrollen entspricht. Während all
dies passiert, ist das Dataset immer noch aktiv und
erreichbar ohne dass eine Ausfallzeit nötig wäre. Sobald
der Schnappschuss zurückgerollt wurde, besitzt das Dataset
den gleichen Zustand, den es besaß, als der Schnappschuss
angelegt wurde. Alle anderen Daten in diesem Dataset, die
nicht Teil des Schnappschusses sind, werden verworfen.
Einen Schnappschuss des aktuellen Zustandes des Datasets vor
dem Zurückrollen anzulegen ist eine gute Idee, wenn
hinterher noch Daten benötigt werden. Auf diese Weise kann
der Benutzer vor und zurück zwischen den Schnappschüssen
springen, ohne wertvolle Daten zu verlieren.snapshotname
Im ersten Beispiel wird ein Schnappschuss aufgrund eines
unvorsichtigen rm
-Befehls zurückgerollt,
der mehr Daten gelöscht hat, als vorgesehen.
#
zfs list -rt all
NAME USED AVAIL REFER MOUNTPOINT mypool/var/tmp 262K 93.2G 120K /var/tmp mypool/var/tmp@my_recursive_snapshot 88K - 152K - mypool/var/tmp@after_cp 53.5K - 118K - mypool/var/tmp@diff_snapshot 0 - 120K -mypool/var/tmp
#
ls /var/tmp
passwd passwd.copy vi.recover#
rm /var/tmp/passwd*
#
ls /var/tmp
vi.recover#
Zu diesem Zeitpunkt bemerkt der Benutzer, dass zuviele Dateien gelöscht wurden und möchte diese zurück haben. ZFS bietet eine einfache Möglichkeit, diese durch zurückrollen zurück zu bekommen, allerdings nur, wenn Schnappschüsse von wichtigen Daten regelmäßig angelegt werden. Um die Dateien zurückzuerhalten und vom letzten Schnappschuss wieder zu beginnen, geben Sie ein:
#
zfs rollback
mypool/var/tmp@diff_snapshot
#
ls /var/tmp
passwd passwd.copy vi.recover
Die Operation zum Zurückrollen versetzt das Dataset in den Zustand des letzten Schnappschusses zurück. Es ist ebenfalls möglich, zu einem Schnappschuss zurückzurollen, der viel früher angelegt wurde und es noch Schnappschüsse nach diesem gibt. Wenn Sie dies versuchen, gibt ZFS die folgende Warnung aus:
#
zfs list -rt snapshot
AME USED AVAIL REFER MOUNTPOINT mypool/var/tmp@my_recursive_snapshot 88K - 152K - mypool/var/tmp@after_cp 53.5K - 118K - mypool/var/tmp@diff_snapshot 0 - 120K -mypool/var/tmp
#
zfs rollback
cannot rollback to 'mypool/var/tmp@my_recursive_snapshot': more recent snapshots exist use '-r' to force deletion of the following snapshots: mypool/var/tmp@after_cp mypool/var/tmp@diff_snapshotmypool/var/tmp@my_recursive_snapshot
Diese Warnung bedeutet, dass noch Schnappschüsse
zwischen dem momentanen Stand des Datasets und dem
Schnappschuss, zu dem der Benutzer zurückrollen möchte,
existieren. Um das Zurückrollen durchzuführen, müssen die
Schnappschüsse gelöscht werden. ZFS kann
nicht alle Änderungen zwischen verschiedenen Zuständen
eines Datasets verfolgen, da Schnappschüsse nur gelesen
werden können. ZFS wird nicht die
betroffenen Schnappschüsse löschen, es sei denn, der
Benutzer verwendet die Option -r
, um
anzugeben, dass dies die gewünschte Aktion ist. Falls dies
der Fall ist und die Konsequenzen alle dazwischenliegenden
Schnappschüsse zu verlieren verstanden wurden, kann der
Befehl abgesetzt werden:
#
zfs rollback -r
mypool/var/tmp@my_recursive_snapshot
#
zfs list -rt snapshot
NAME USED AVAIL REFER MOUNTPOINT mypool/var/tmp@my_recursive_snapshot 8K - 152K -mypool/var/tmp
#
ls /var/tmp
vi.recover
Die Ausgabe von zfs list -t snapshot
bestätigt, dass die dazwischenliegenden Schnappschüsse als
Ergebnis von zfs rollback -r
entfernt
wurden.
Schnappschüsse sind unter einem versteckten Verzeichnis
unter dem Eltern-Dataset eingehängt:
.zfs/snapshots/
.
Standardmäßig werden diese Verzeichnisse nicht von einem
gewöhnlichen snapshotname
ls -a
angezeigt. Obwohl
diese Verzeichnisse nicht angezeigt werden, sind diese
trotzdem vorhanden und der Zugriff darauf erfolgt wie auf
jedes andere Verzeichnis. Die Eigenschaft
snapdir
steuert, ob diese Verzeichnisse
beim Auflisten eines Verzeichnisses angezeigt werden oder
nicht. Das Einstellen der Eigenschaft auf den Wert
visible
erlaubt es, diese in der Ausgabe
von ls
und anderen Kommandos, die
mit Verzeichnisinhalten umgehen können, anzuzeigen.
#
zfs get snapdir
NAME PROPERTY VALUE SOURCE mypool/var/tmp snapdir hidden defaultmypool/var/tmp
#
ls -a /var/tmp
. .. passwd vi.recover#
zfs set snapdir=visible
mypool/var/tmp
#
ls -a /var/tmp
. .. .zfs passwd vi.recover
Einzelne Dateien lassen sich einfach auf einen
vorherigen Stand wiederherstellen, indem diese aus dem
Schnappschuss zurück in das Eltern-Dataset kopiert werden.
Die Verzeichnisstruktur unterhalb von
.zfs/snapshot
enthält ein Verzeichnis,
das exakt wie der Schnappschuss benannt ist, der zuvor
angelegt wurde, um es einfacher zu machen, diese zu
identifizieren. Im nächsten Beispiel wird angenommen, dass
eine Datei aus dem versteckten
.zfs
Verzeichnis durch kopieren aus dem
Schnappschuss, der die letzte Version dieser Datei enthielt,
wiederhergestellt wird:
#
rm /var/tmp/passwd
#
ls -a /var/tmp
. .. .zfs vi.recover#
ls /var/tmp/.zfs/snapshot
after_cp my_recursive_snapshot#
ls /var/tmp/.zfs/snapshot/
passwd vi.recoverafter_cp
#
cp /var/tmp/.zfs/snapshot/
after_cp/passwd
/var/tmp
Als ls .zfs/snapshot
ausgeführt
wurde, war die snapdir
-Eigenschaft
möglicherweise nicht auf hidden gesetzt, trotzdem ist es
immer noch möglich, den Inhalt dieses Verzeichnisses
aufzulisten. Es liegt am Administrator zu entscheiden, ob
diese Verzeichnisse angezeigt werden soll. Es ist möglich,
diese für bestimmte Datasets anzuzeigen und für andere zu
verstecken. Das Kopieren von Dateien oder Verzeichnissen
aus diesem versteckten .zfs/snapshot
Verzeichnis ist einfach genug. Jedoch führt der umgekehrte
Weg zu einem Fehler:
#
cp
cp: /var/tmp/.zfs/snapshot/after_cp/rc.conf: Read-only file system/etc/rc.conf
/var/tmp/.zfs/snapshot/after_cp/
Der Fehler erinnert den Benutzer daran, dass Schnappschüsse nur gelesen aber nicht mehr geändert werden können, nachdem diese angelegt wurden. Es können keine Dateien in diese Schnappschuss-Verzeichnisse kopiert oder daraus gelöscht werden, da dies sonst den Zustand des Datasets verändern würde, den sie repräsentieren.
Schnappschüsse verbrauchen Speicherplatz basierend auf
der Menge an Änderungen, die am Eltern-Dataset durchgeführt
wurden, seit der Zeit als der Schnappschuss erstellt wurde.
Die Eigenschaft written
eines
Schnappschusses verfolgt, wieviel Speicherplatz vom
Schnappschuss belegt wird.
Schnappschüsse werden zerstört und der belegte Platz
wieder freigegeben durch den Befehl
zfs destroy
.
Durch hinzufügen von dataset
@snapshot
-r
werden alle
Schnappschüsse rekursiv gelöscht, die den gleichen Namen wie
das Eltern-Dataset besitzen. Mit der Option
-n -v
wird eine Liste von Schnappschüssen,
die gelöscht werden würden, zusammen mit einer geschätzten
Menge an zurückgewonnenem Speicherplatz angezeigt, ohne die
eigentliche Zerstöroperation wirklich durchzuführen.
Ein Klon ist eine Kopie eines Schnappschusses, der mehr
wie ein reguläres Dataset behandelt wird. Im Gegensatz zu
Schnappschüssen kann man von einem Klon nicht nur lesen, er
ist eingehängt und kann seine eigenen Eigenschaften haben.
Sobald ein Klon mittels zfs clone
erstellt
wurde, lässt sich der zugrundeliegende Schnappschuss nicht
mehr zerstören. Die Eltern-/Kindbeziehung zwischen dem Klon
und dem Schnappschuss kann über
zfs promote
aufgelöst werden. Nachdem ein
Klon auf diese Weise befördert wurde, wird der Schnappschuss
zum Kind des Klons, anstatt des ursprünglichen Datasets. Dies
wird die Art und Weise, wie der Speicherplatz berechnet wird,
verändern, jedoch nicht den bereits belegten Speicher
anpassen. Der Klon kann an einem beliebigen Punkt innerhalb
der ZFS-Dateisystemhierarchie eingehängt
werden, nur nicht unterhalb der ursprünglichen Stelle des
Schnappschusses.
Um diese Klon-Funktionalität zu demonstrieren, wird dieses Beispiel-Dataset verwendet:
#
zfs list -rt all
NAME USED AVAIL REFER MOUNTPOINT camino/home/joe 108K 1.3G 87K /usr/home/joe camino/home/joe@plans 21K - 85.5K - camino/home/joe@backup 0K - 87K -camino/home/joe
Ein typischer Einsatzzweck für Klone ist das experimentieren mit einem bestimmten Dataset, während der Schnappschuss beibehalten wird für den Fall, dass etwas schiefgeht. Da Schnappschüsse nicht verändert werden können, wird ein Lese-/Schreibklon des Schnappschusses angelegt. Nachdem das gewünschte Ergebnis im Klon erreicht wurde, kann der Klon zu einem Dataset ernannt und das alte Dateisystem entfernt werden. Streng genommen ist das nicht nötig, da der Klon und das Dataset ohne Probleme miteinander koexistieren können.
#
zfs clone
camino/home/joe
@backup
camino/home/joenew
#
ls /usr/home/joe*
/usr/home/joe: backup.txz plans.txt /usr/home/joenew: backup.txz plans.txt#
df -h /usr/home
Filesystem Size Used Avail Capacity Mounted on usr/home/joe 1.3G 31k 1.3G 0% /usr/home/joe usr/home/joenew 1.3G 31k 1.3G 0% /usr/home/joenew
Nachdem ein Klon erstellt wurde, stellt er eine exakte
Kopie des Datasets zu dem Zeitpunkt dar, als der Schnappschuss
angelegt wurde. Der Klon kann nun unabhängig vom
ursprünglichen Dataset geändert werden. Die einzige
Verbindung zwischen den beiden ist der Schnappschuss.
ZFS zeichnet diese Verbindung in der
Eigenschaft namens origin
auf. Sobald die
Abhängigkeit zwischen dem Schnappschuss und dem Klon durch das
Befördern des Klons mittels zfs promote
entfernt wurde, wird auch die
origin
-Eigenschaft des Klons entfernt, da
es sich nun um ein eigenständiges Dataset handelt. Dieses
Beispiel demonstriert dies:
#
zfs get origin
NAME PROPERTY VALUE SOURCE camino/home/joenew origin camino/home/joe@backup -camino/home/joenew
#
zfs promote
camino/home/joenew
#
zfs get origin
NAME PROPERTY VALUE SOURCE camino/home/joenew origin - -camino/home/joenew
Nachdem ein paar Änderungen, wie beispielsweise das
Kopieren von loader.conf
auf den
beförderten Klon vorgenommen wurden, wird das alte Verzeichnis
in diesem Fall überflüssig. Stattdessen kann der beförderte
Klon diesen ersetzen. Dies kann durch zwei
aufeinanderfolgende Befehl geschehen: zfs
destroy
auf dem alten Dataset und zfs
rename
auf dem Klon, um diesen genauso wie das
alte Dataset zu benennen (es kann auch einen ganz anderen
Namen erhalten).
#
cp
/boot/defaults/loader.conf
/usr/home/joenew
#
zfs destroy -f
camino/home/joe
#
zfs rename
camino/home/joenew
camino/home/joe
#
ls /usr/home/joe
backup.txz loader.conf plans.txt#
df -h
Filesystem Size Used Avail Capacity Mounted on usr/home/joe 1.3G 128k 1.3G 0% /usr/home/joe/usr/home
Der geklonte Schnappschuss wird jetzt wie ein
gewöhnliches Dataset behandelt. Es enthält alle Daten aus dem
ursprünglichen Schnappschuss inklusive der Dateien, die
anschließend hinzugefügt wurden, wie
loader.conf
. Klone können in
unterschiedlichen Szenarien eingesetzt werden, um nützliche
Eigenschaften für ZFS-Anwender zur Verfügung zu stellen.
Zum Beispiel können Jails als Schnappschüsse bereitgestellt
werden, die verschiedene Arten von installierten Anwendungen
anbieten. Anwender können diese Schnappschüsse klonen und
ihre eigenen Anwendungen nach Belieben hinzufügen. Sobald
sie mit den Änderungen zufrieden sind, können die Klone zu
vollständigen Datasets ernannt werden und dem Anwender zur
Verfügung gestellt werden, als würde es sich um echte
Datasets handeln. Das spart Zeit und Administrationsaufwand,
wenn diese Jails auf diese Weise zur Verfügung gestellt
werden.
Daten auf einem einzigen Pool an einem Platz
aufzubewahren, setzt diese dem Risiko aus, gestohlen oder
Opfer von Naturgewalten zu werden, sowie menschlichem
Versagen auszusetzen. Regelmäßige Sicherungen des gesamten
Pools ist daher unerlässlich. ZFS bietet
eine Reihe von eingebauten Serialisierungsfunktionen an, die
in der Lage ist, eine Repräsentation der Daten als Datenstrom
auf die Standardausgabe zu schreiben. Mit dieser Methode ist
es nicht nur möglich, die Daten auf einen anderen Pool zu
schicken, der an das lokale System angeschlossen ist, sondern
ihn auch über ein Netzwerk an ein anderes System zu senden.
Schnappschüsse stellen dafür die Replikationsbasis bereit
(lesen Sie dazu den Abschnitt zu ZFS
snapshots). Die Befehle, die für die Replikation
verwendet werden, sind zfs send
und
zfs receive
.
Diese Beispiele demonstrieren die Replikation von ZFS anhand dieser beiden Pools:
#
zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT backup 960M 77K 896M - - 0% 0% 1.00x ONLINE - mypool 984M 43.7M 940M - - 0% 4% 1.00x ONLINE -
Der Pool namens mypool
ist der
primäre Pool, auf den regelmäßig Daten geschrieben und auch
wieder gelesen werden. Ein zweiter Pool, genannt
backup
wird verwendet, um als
Reserve zu dienen im Falle, dass der primäre Pool nicht zur
Verfügung steht. Beachten Sie, dass diese Ausfallsicherung
nicht automatisch von ZFS durchgeführt
wird, sondern manuell von einem Systemadministrator bei Bedarf
eingerichtet werden muss. Ein Schnappschuss wird verwendet,
um einen konsistenten Zustand des Dateisystems, das repliziert
werden soll, zu erzeugen. Sobald ein Schnappschuss von
mypool
angelegt wurde, kann er auf
den backup
-Pool abgelegt werden.
Nur Schnappschüsse lassen sich auf diese Weise replizieren.
Änderungen, die seit dem letzten Schnappschuss entstanden
sind, werden nicht mit repliziert.
#
zfs snapshot
mypool
@backup1
#
zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT mypool@backup1 0 - 43.6M -
Da nun ein Schnappschuss existiert, kann mit
zfs send
ein Datenstrom, der den Inhalt des
Schnappschusses repräsentiert, erstellt werden. Dieser
Datenstrom kann als Datei gespeichert oder von einem
anderen Pool empfangen werden. Der Datenstrom wird auf die
Standardausgabe geschrieben, muss jedoch in eine Datei oder
in eine Pipe umgeleitet werden, sonst wird ein Fehler
produziert:
#
zfs send
Error: Stream can not be written to a terminal. You must redirect standard output.mypool
@backup1
Um ein Dataset mit zfs send
zu
replizieren, leiten Sie dieses in eine Datei auf dem
eingehängten Backup-Pool um. Stellen Sie sicher, dass der
Pool genug freien Speicherplatz besitzt, um die Größe des
gesendeten Schnappschusses aufzunehmen. Das beinhaltet alle
Daten im Schnappschuss, nicht nur die Änderungen zum
vorherigen Schnappschuss.
#
zfs send
mypool
@backup1
>/backup/backup1
#
zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT backup 960M 63.7M 896M - - 0% 6% 1.00x ONLINE - mypool 984M 43.7M 940M - - 0% 4% 1.00x ONLINE -
Das Kommando zfs send
transferierte
alle Daten im backup1
-Schnappschuss
auf den Pool namens backup
.
Erstellen und senden eines Schnappschusses kann automatisch
von cron(8) durchgeführt werden.
Anstatt die Sicherungen als Archivdateien zu speichern,
kann ZFS diese auch als aktives Dateisystem
empfangen, was es erlaubt, direkt auf die gesicherten Daten
zuzugreifen. Um an die eigentlichen Daten in diesem Strom zu
gelangen, wird zfs receive
benutzt, um den
Strom wieder in Dateien und Verzeichnisse umzuwandeln. Das
Beispiel unten kombiniert zfs send
und
zfs receive
durch eine Pipe, um die Daten
von einem Pool auf den anderen zu kopieren. Die Daten können
direkt auf dem empfangenden Pool verwendet werden, nachdem der
Transfer abgeschlossen ist. Ein Dataset kann nur auf ein
leeres Dataset repliziert werden.
#
zfs snapshot
mypool
@replica1
#
zfs send -v
send from @ to mypool@replica1 estimated size is 50.1M total estimated size is 50.1M TIME SENT SNAPSHOTmypool
@replica1
| zfs receivebackup/mypool
#
zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT backup 960M 63.7M 896M - - 0% 6% 1.00x ONLINE - mypool 984M 43.7M 940M - - 0% 4% 1.00x ONLINE -
Die Unterschiede zwischen zwei Schnappschüssen kann
zfs send
ebenfalls erkennen und nur diese
übertragen. Dies spart Speicherplatz und Übertragungszeit.
Beispielsweise:
#
zfs snapshot
mypool
@replica2
#
zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT mypool@replica1 5.72M - 43.6M - mypool@replica2 0 - 44.1M -#
zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT backup 960M 61.7M 898M - - 0% 6% 1.00x ONLINE - mypool 960M 50.2M 910M - - 0% 5% 1.00x ONLINE -
Ein zweiter Schnappschuss genannt
replica2
wurde angelegt. Dieser
zweite Schnappschuss enthält nur die Änderungen, die
zwischen dem jetzigen Stand des Dateisystems und dem
vorherigen Schnappschuss,
replica1
, vorgenommen wurden.
Durch zfs send -i
und die Angabe des
Schnappschusspaares wird ein inkrementeller
Replikationsstrom erzeugt, welcher nur die Daten enthält,
die sich geändert haben. Das kann nur erfolgreich sein,
wenn der initiale Schnappschuss bereits auf der
Empfängerseite vorhanden ist.
#
zfs send -v -i
send from @replica1 to mypool@replica2 estimated size is 5.02M total estimated size is 5.02M TIME SENT SNAPSHOTmypool
@replica1
mypool
@replica2
| zfs receive/backup/mypool
#
zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT backup 960M 80.8M 879M - - 0% 8% 1.00x ONLINE - mypool 960M 50.2M 910M - - 0% 5% 1.00x ONLINE -#
zfs list
NAME USED AVAIL REFER MOUNTPOINT backup 55.4M 240G 152K /backup backup/mypool 55.3M 240G 55.2M /backup/mypool mypool 55.6M 11.6G 55.0M /mypool#
zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT backup/mypool@replica1 104K - 50.2M - backup/mypool@replica2 0 - 55.2M - mypool@replica1 29.9K - 50.0M - mypool@replica2 0 - 55.0M -
Der inkrementelle Datenstrom wurde erfolgreich
übertragen. Nur die Daten, die verändert wurden, sind
übertragen worden, anstatt das komplette
replica1
. Nur die Unterschiede
wurden gesendet, was weniger Zeit und Speicherplatz in
Anspruch genommen hat, statt jedesmal den gesamten Pool zu
kopieren. Das ist hilfreich wenn langsame Netzwerke oder
Kosten für die übertragene Menge Bytes in Erwägung gezogen
werden müssen.
Ein neues Dateisystem,
backup/mypool
, ist mit allen
Dateien und Daten vom Pool
mypool
verfügbar. Wenn die
Option -P
angegeben wird, werden die
Eigenschaften des Datasets kopiert, einschließlich der
Komprimierungseinstellungen, Quotas und Einhängepunkte.
Wird die Option -R
verwendet, so werden
alle Kind-Datasets des angegebenen Datasets kopiert,
zusammen mit ihren Eigenschaften. Senden und Empfangen kann
automatisiert werden, so dass regelmäßig Sicherungen auf
dem zweiten Pool angelegt werden.
Datenströme über das Netzwerk zu schicken ist eine gute Methode, um Sicherungen außerhalb des Systems anzulegen. Jedoch ist dies auch mit einem Nachteil verbunden. Daten, die über die Leitung verschickt werden, sind nicht verschlüsselt, was es jedem erlaubt, die Daten abzufangen und die Ströme wieder zurück in Daten umzuwandeln, ohne dass der sendende Benutzer davon etwas merkt. Dies ist eine unerwünschte Situation, besonders wenn die Datenströme über das Internet auf ein entferntes System gesendet werden. SSH kann benutzt werden, um durch Verschlüsselung geschützte Daten über eine Netzwerkverbindung zu übertragen. Da ZFS nur die Anforderung hat, dass der Strom von der Standardausgabe umgeleitet wird, ist es relativ einfach, diesen durch SSH zu leiten. Um den Inhalt des Dateisystems während der Übertragung und auf dem entfernten System weiterhin verschlüsselt zu lassen, denken Sie über den Einsatz von PEFS nach.
Ein paar Einstellungen und Sicherheitsvorkehrungen
müssen zuvor abgeschlossen sein. Es werden hier nur die
nötigen Schritte für die zfs send
-Aktion
gezeigt. Weiterführende Informationen zu
SSH, gibt es im Kapitel
Abschnitt 13.8, „OpenSSH“.
Die folgende Konfiguration wird benötigt:
Passwortloser SSH-Zugang zwischen dem sendenden und dem empfangenden Host durch den Einsatz von SSH-Schlüsseln.
Normalerweise werden die Privilegien des root
-Benutzers
gebraucht, um Strom zu senden und zu empfangen. Das
beinhaltet das Anmelden auf dem empfangenden System als
root
.
Allerdings ist das Anmelden als root
aus
Sicherheitsgründen standardmäßig deaktiviert. Mit
ZFS Delegation
lassen sich nicht-root
-Benutzer auf jedem
System einrichten, welche die nötigen Rechte besitzen,
um die Sende- und Empfangsoperation
durchzuführen.
Auf dem sendenden System:
#
zfs allow -u someuser send,snapshot
mypool
Um den Pool einzuhängen, muss der unprivilegierte Benutzer das Verzeichnis besitzen und gewöhnliche Benutzern muss die Erlaubnis gegeben werden, das Dateisystem einzuhängen. Auf dem empfangenden System nehmen Sie dazu die folgenden Einstellungen vor:
#
sysctl vfs.usermount=1
vfs.usermount: 0 -> 1#
echo vfs.usermount=1 >> /etc/sysctl.conf
#
zfs create
recvpool/backup
#
zfs allow -u
someuser
create,mount,receiverecvpool/backup
#
chown
someuser
/recvpool/backup
Der unprivilegierte Benutzer hat jetzt die Fähigkeit,
Datasets zu empfangen und einzuhängen und das
home
-Dataset auf das entfernte
System zu replizieren:
%
zfs snapshot -r
mypool/home
@monday
%
zfs send -R
mypool/home
@monday
| sshsomeuser@backuphost
zfs recv -dvurecvpool/backup
Ein rekursiver Schnappschuss namens
monday
wird aus dem Dataset
home
erstellt, dass auf dem Pool
mypool
liegt. Es wird dann mit
zfs send -R
gesendet, um das Dataset,
alle seine Kinder, Schnappschüsse, Klone und Einstellungen
in den Strom mit aufzunehmen. Die Ausgabe wird an das
wartende System backuphost
mittels zfs receive
durch
SSH umgeleitet. Die Verwendung
des Fully Qulified Domänennamens oder der IP-Adresse wird
empfohlen. Die empfangende Maschine schreibt die Daten auf
das backup
-Dataset im
recvpool
-Pool. Hinzufügen der
Option -d
zu zfs recv
überschreibt den Namen des Pools auf der empfangenden Seite
mit dem Namen des Schnappschusses. Durch Angabe von
-u
wird das Dateisystem nicht auf der
Empfängerseite eingehängt. Wenn -v
enthalten ist, werden mehr Details zum Transfer angezeigt
werden, einschließlich der vergangenen Zeit und der Menge
an übertragenen Daten.
Dataset-Quotas werden eingesetzt, um den Speicherplatz einzuschränken, den ein bestimmtes Dataset verbrauchen kann. Referenz-Quotas funktionieren auf eine ähnliche Weise, jedoch wird dabei der Speicherplatz des Datasets selbst gezählt, wobei Schnappschüsse und Kind-Datasets dabei ausgenommen sind. Ähnlich dazu werden Benutzer- und Gruppen-Quotas dazu verwendet, um Benutzer oder Gruppen daran zu hindern, den gesamten Speicherplatz im Pool oder auf dem Dataset zu verbrauchen.
Die folgenden Beispiele gehen davon aus, dass die Benutzer
bereits im System vorhanden sind. Bevor Sie einen Benutzer
hinzufügen, stellen Sie sicher, dass Sie zuerst ein Dataset
für das Heimatverzeichnis anlegen und den
mountpoint
auf
/home/
festlegen. Legen Sie dann den Benutzer an und stellen Sie
sicher, dass das Heimatverzeichnis auf den auf den
bob
mountpoint
des Datasets verweist. Auf diese
Weise werden die Eigentümer- und Gruppenberechtigungen richtig
gesetzt, ohne dass bereits vorhandene Heimatverzeichnisse
verschleiert werden.
Um ein 10 GB großes Quota auf dem Dataset
storage/home/bob
zu erzwingen, verwenden
Sie folgenden Befehl:
#
zfs set quota=10G storage/home/bob
Um ein Referenzquota von 10 GB für
storage/home/bob
festzulegen, geben Sie
ein:
#
zfs set refquota=10G storage/home/bob
Um das Quota für storage/home/bob
wieder zu entfernen:
#
zfs set quota=none storage/home/bob
Das generelle Format ist
userquota@
und der Name des Benutzers muss in einem der folgenden Formate
vorliegen:user
=size
POSIX-kompatibler Name wie
joe
.
POSIX-numerische ID wie
789
.
SID-Name wie
joe.bloggs@example.com
.
SID-numerische ID wie
S-1-123-456-789
.
Um beispielsweise ein Benutzerquota von 50 GB für
den Benutzer names joe
zu
erzwingen:
#
zfs set userquota@joe=50G
Um jegliche Quotas zu entfernen:
#
zfs set userquota@joe=none
Benutzerquota-Eigenschaften werden nicht von
zfs get all
dargestellt.
Nicht-root
-Benutzer können nur ihre
eigenen Quotas sehen, ausser ihnen wurde das
userquota
-Privileg zugeteilt. Benutzer
mit diesem Privileg sind in der Lage, jedermanns Quota zu
sehen und zu verändern.
Das generelle Format zum Festlegen einer Gruppenquota
lautet:
groupquota@
.group
=size
Um ein Quota für die Gruppe
firstgroup
von 50 GB zu
setzen, geben Sie ein:
#
zfs set groupquota@firstgroup=50G
Um eine Quota für die Gruppe
firstgroup
zu setzen oder
sicherzustellen, dass diese nicht gesetzt ist, verwenden Sie
stattdessen:
#
zfs set groupquota@firstgroup=none
Genau wie mit der Gruppenquota-Eigenschaft, werden
nicht-root
-Benutzer
nur die Quotas sehen, die den Gruppen zugeordnet ist, in denen
Sie Mitglied sind. Allerdings ist root
oder ein Benutzer mit dem
groupquota
-Privileg in der Lage, die Quotas
aller Gruppen zu sehen und festzusetzen.
Um die Menge an Speicherplatz zusammen mit der Quota
anzuzeigen, die von jedem Benutzer auf dem Dateisystem oder
Schnappschuss verbraucht wird, verwenden Sie
zfs userspace
. Für Gruppeninformationen,
nutzen Sie zfs groupspace
. Für weitere
Informationen zu unterstützten Optionen oder wie sich nur
bestimmte Optionen anzeigen lassen, lesen Sie
zfs(1).
Benutzer mit ausreichenden Rechten sowie root
können das Quota für
storage/home/bob
anzeigen lassen:
#
zfs get quota storage/home/bob
Reservierungen garantieren ein Minimum an Speicherplatz, der immer auf dem Dataset verfügbar sein wird. Der reservierte Platz wird nicht für andere Datasets zur Verfügung stehen. Diese Eigenschaft kann besonders nützlich sein, um zu gewährleisten, dass freier Speicherplatz für ein wichtiges Dataset oder für Logdateien bereit steht.
Das generelle Format der
reservation
-Eigenschaft ist
reservation=
.
Um also eine Reservierung von 10 GB auf
size
storage/home/bob
festzulegen, geben Sie
Folgendes ein:
#
zfs set reservation=10G storage/home/bob
Um die Reservierung zu beseitigen:
#
zfs set reservation=none storage/home/bob
Das gleiche Prinzip kann auf die
refreservation
-Eigenschaft angewendet
werden, um eine Referenzreservierung
mit dem generellen Format
refreservation=
festzulegen.size
Dieser Befehl zeigt die Reservierungen oder
Referenzreservierungen an, die auf
storage/home/bob
existieren:
#
zfs get reservation storage/home/bob
#
zfs get refreservation storage/home/bob
ZFS bietet transparente Komprimierung. Datenkomprimierung auf Blockebene während diese gerade geschrieben werden, spart nicht nur Plattenplatz ein, sondern kann auch den Durchsatz der Platte steigern. Falls Daten zu 25% komprimiert sind, jedoch die komprimierten Daten im gleichen Tempo wie ihre unkomprimierte Version, resultiert das in einer effektiven Schreibgeschwindigkeit von 125%. Komprimierung kann auch eine Alternative zu Deduplizierung darstellen, da es viel weniger zusätzlichen Hauptspeicher benötigt.
ZFS bietet mehrere verschiedene Kompressionsalgorithmen an, jede mit unterschiedlichen Kompromissen. Mit der Einführung von LZ4-Komprimierung in ZFS v5000, ist es möglich, Komprimierung für den gesamten Pool zu aktivieren, ohne die großen Geschwindigkeitseinbußen der anderen Algorithmen. Der größte Vorteil von LZ4 ist die Eigenschaft früher Abbruch. Wenn LZ4 nicht mindestens 12,5% Komprimierung im ersten Teil der Daten erreicht, wird der Block unkomprimiert geschrieben, um die Verschwendung von CPU-Zyklen zu vermeiden, weil die Daten entweder bereits komprimiert sind oder sich nicht komprimieren lassen. Für Details zu den verschiedenen verfügbaren Komprimierungsalgorithmen in ZFS, lesen Sie den Eintrag Komprimierung im Abschnitt Terminologie
Der Administrator kann die Effektivität der Komprimierung über eine Reihe von Dataset-Eigenschaften überwachen.
#
zfs get used,compressratio,compression,logicalused
NAME PROPERTY VALUE SOURCE mypool/compressed_dataset used 449G - mypool/compressed_dataset compressratio 1.11x - mypool/compressed_dataset compression lz4 local mypool/compressed_dataset logicalused 496G -mypool/compressed_dataset
Dieses Dataset verwendet gerade 449 GB Plattenplatz
(used-Eigenschaft. Ohne Komprimierung würde es stattdessen
496 GB Plattenplatz belegen
(logicalused
). Das ergibt eine
Kompressionsrate von 1,11:1.
Komprimierung kann einen unerwarteten Nebeneffekt haben,
wenn diese mit Benutzerquotas
kombiniert wird. Benutzerquotas beschränken, wieviel
Speicherplatz ein Benutzer auf einem Dataset verbrauchen kann.
Jedoch basieren die Berechnungen darauf, wieviel Speicherplatz
nach der Komprimierung belegt ist. Wenn
also ein Benutzer eine Quota von10 GB besitzt und
10 GB von komprimierbaren Daten schreibt, wird dieser
immer noch in der Lage sein, zusätzliche Daten zu speichern.
Wenn später eine Datei aktualisiert wird, beispielsweise eine
Datenbank, mit mehr oder weniger komprimierbaren Daten, wird
sich die Menge an verfügbarem Speicherplatz ändern. Das
kann in einer merkwürdigen Situation resultieren, in welcher
der Benutzer nicht die eigentliche Menge an Daten (die
Eigenschaft logicalused
) überschreitet,
jedoch die Änderung in der Komprimierung dazu führt, dass das
Quota-Limit erreicht ist.
Kompression kann ebenso unerwartet mit Sicherungen interagieren. Quotas werden oft verwendet, um einzuschränken, wieviele Daten gespeichert werden können um sicherzustellen, dass ausreichend Speicherplatz für die Sicherung vorhanden ist. Wenn jedoch Quotas Komprimierung nicht berücksichtigen, werden womöglich mehr Daten geschrieben als in der unkomprimierten Sicherung Platz ist.
Wenn aktiviert, verwendet Deduplizierung die Prüfsumme jedes Blocks, um Duplikate dieses Blocks zu ermitteln. Sollte ein neuer Block ein Duplikat eines existierenden Blocks sein, dann schreibt ZFS eine zusätzliche Referenz auf die existierenden Daten anstatt des kompletten duplizierten Blocks. Gewaltige Speicherplatzeinsparungen sind möglich wenn die Daten viele Duplikate von Dateien oder wiederholte Informationen enthalten. Seien Sie gewarnt: Deduplizierung benötigt eine extrem große Menge an Hauptspeicher und die meistens Einsparungen können stattdessen durch das Aktivieren von Komprimierung erreicht werden.
Um Deduplizierung zu aktivieren, setzen Sie die
dedup
-Eigenschaft auf dem Zielpool:
#
zfs set dedup=on
pool
Nur neu auf den Pool geschriebene Daten werden dedupliziert. Daten, die bereits auf den Pool geschrieben wurden, werden nicht durch das Aktivieren dieser Option dedupliziert. Ein Pool mit einer gerade aktivierten Deduplizierung wird wie in diesem Beispiel aussehen:
#
zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT pool 2.84G 2.19M 2.83G - - 0% 0% 1.00x ONLINE -
Die Spalte DEDUP
zeigt das aktuelle
Verhältnis der Deduplizierung für diesen Pool an. Ein Wert
von 1.00x
zeigt an, dass die Daten noch
nicht dedupliziert wurden. Im nächsten Beispiel wird die
Ports-Sammlung dreimal in verschiedene Verzeichnisse auf dem
deduplizierten Pool kopiert.
#
for d in dir1 dir2 dir3; do
>mkdir $d && cp -R /usr/ports $d &
>done
Redundante Daten werden erkannt und dedupliziert:
#
zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT pool 2.84G 20.9M 2.82G 0% 3.00x ONLINE -
Die DEDUP
-Spalte zeigt einen Faktor von
3.00x
. Mehrere Kopien der Ports-Sammlung
wurden erkannt und dedupliziert, was nur ein Drittel des
Speicherplatzes benötigt. Das Potential für Einsparungen beim
Speicherplatz ist enorm, wird jedoch damit erkauft, dass
genügend Speicher zur Verfügung stehen muss, um die
deduplizierten Blöcke zu verwalten.
Deduplizierung ist nicht immer gewinnbringend, besonders wenn die Daten auf dem Pool nicht redundant sind. ZFS kann potentielle Speicherplatzeinsparungen durch Deduplizierung auf einem Pool simulieren:
#
zdb -S
Simulated DDT histogram: bucket allocated referenced ______ ______________________________ ______________________________ refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE ------ ------ ----- ----- ----- ------ ----- ----- ----- 1 2.58M 289G 264G 264G 2.58M 289G 264G 264G 2 206K 12.6G 10.4G 10.4G 430K 26.4G 21.6G 21.6G 4 37.6K 692M 276M 276M 170K 3.04G 1.26G 1.26G 8 2.18K 45.2M 19.4M 19.4M 20.0K 425M 176M 176M 16 174 2.83M 1.20M 1.20M 3.33K 48.4M 20.4M 20.4M 32 40 2.17M 222K 222K 1.70K 97.2M 9.91M 9.91M 64 9 56K 10.5K 10.5K 865 4.96M 948K 948K 128 2 9.50K 2K 2K 419 2.11M 438K 438K 256 5 61.5K 12K 12K 1.90K 23.0M 4.47M 4.47M 1K 2 1K 1K 1K 2.98K 1.49M 1.49M 1.49M Total 2.82M 303G 275G 275G 3.20M 319G 287G 287G dedup = 1.05, compress = 1.11, copies = 1.00, dedup * compress / copies = 1.16pool
Nachdem zdb -S
die Analyse des Pool
abgeschlossen hat, zeigt es die Speicherplatzeinsparungen, die
durch aktivierte Deduplizierung erreichbar sind, an. In
diesem Fall ist 1.16
ein sehr schlechter
Faktor, der größtenteils von Einsparungen durch Komprimierung
beeinflusst wird. Aktivierung von Deduplizierung auf diesem
Pool würde also keine signifikante Menge an Speicherplatz
einsparen und ist daher nicht die Menge an Speicher wert, die
nötig sind, um zu deduplizieren. Über die Formel
ratio = dedup * compress / copies kann
ein Systemadministrator die Speicherplatzbelegung planen und
entscheiden, ob es sich lohnt, den zusätzlichen Hauptspeicher
für die Deduplizierung anhand des späteren Workloads
aufzuwenden. Wenn sich die Daten verhältnismäßig gut
komprimieren lassen, sind die Speicherplatzeinsparungen sehr
gut. Es wird empfohlen, in dieser Situation zuerst die
Komprimierung zu aktivieren, da diese auch erhöhte
Geschwindigkeit mit sich bringt. Aktivieren Sie
Deduplizierung nur in solchen Fällen, bei denen die
Einsparungen beträchtlich sind und genug Hauptspeicher zur
Verfügung steht, um die DDT
aufzunehmen.
Um ein ZFS-Dataset einem
Jail zuzuweisen, wird der Befehl
zfs jail
und die dazugehörige Eigenschaft
jailed
verwendet. Durch Angabe von
zfs jail
wird ein Dataset dem spezifizierten Jail zugewiesen und kann
mit jailid
zfs unjail
wieder abgehängt werden.
Damit das Dataset innerhalb der Jail kontrolliert werden kann,
muss die Eigenschaft jailed
gesetzt sein.
Sobald ein Dataset sich im Jail befindet, kann es nicht mehr
länger auf dem Hostsystem eingehängt werden, da es
Einhängepunkte aufweisen könnte, welche die Sicherheit des
Systems gefährden.
Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an
<de-bsd-questions@de.FreeBSD.org>.
Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an
<de-bsd-translators@de.FreeBSD.org>.