Copy-on-Write Prinzip in ZFS

Aus Thomas-Krenn-Wiki
Zur Navigation springen Zur Suche springen

Copy-on-Write (CoW, dt. "Kopieren-beim-Schreiben") ist ein Optimierungsprinzip der Datenverarbeitung, bei dem Änderungen nicht direkt am bestehenden Datenbestand vorgenommen, sondern immer in eine neue Kopie geschrieben werden. Als Kernstück der Speicherstrategie des Dateisystems ZFS sorgt CoW – in Kombination mit Transaktionsgruppen – dafür, dass ein unterbrochener Schreibvorgang niemals zu einem inkonsistenten Dateisystem führen kann. Das hebt ZFS von klassischen Dateisystemen ab, die Daten direkt überschreiben.

Das Copy-on-Write-Prinzip

Bei Schreibvorgängen nach dem CoW-Prinzip werden Datenblöcke bei Änderungen nicht überschrieben. Stattdessen werden neue Datenblöcke mit den Änderungen beschrieben und die alten Datenblöcke nur abgelöst. Um die Konsistenz der Daten zu erhalten, arbeitet CoW mit einem Referenz-System, das als Hash-Tree (oder auch Merkle-Tree)[1] bekannt ist. Mithilfe dieses Systems wird sichergestellt, das Fehler in der Datenintegrität zu jedem Zeitpunkt erkannt werden können.

Die Baumstruktur

Abb. 1: Ein einfacher Hash-Baum.

In Abbildung 1 ist eine vereinfachte Ansicht eines Hash-Trees zu sehen:

  • An den Endpunkten des Baumes, die auch als leaves (Blätter) bezeichnet werden, stehen die Blöcke mit den Daten.
  • Die darüberliegenden Knoten – inner nodes oder branches (Zweige) genannt – enthalten Block Zeiger (Block Pointer). Jeder diese Zeiger enhtält Informationen über die darunterliegenden Blöcke, z.B. den physischen Ort der Daten, die Größe der Blöcke sowie die Nummer der Transaktionsgruppe (die Birth-TXG), in welche der Block geschrieben wurde. Die wichtigste Information ist aber die Prüfsumme.
  • Über den inner nodes findet sich der root (Wurzel) Knoten, welcher inhaltlich den branches entspricht.
  • Auf der obersten Ebene befindet sich der uberblock. Dieser ist in einem zpool einzigartig und wird nach jedem Schreibvorgang neu errechnet. Er enthält die Prüfsumme, aus welcher sich alle im zpool enthaltenen Daten verifizieren lassen.

Anwendung in Transaktionsgruppen

ZFS hält die Daten zunächst in sogenannten Transaktionsgruppen (txg) im RAM des Systems. Nach einem festgelegten Zeitrahmen – die Standardeinstellung ist 5 Sekunden – oder wenn ausreichend Daten angesammelt wurden, werden alle in der Transaktionsgruppe gesammelten Änderungen gleichzeitig committed[2].

Durch diese Vorgehensweise ist sichergestellt, dass ein inkonsistenter Datenstand durch einen unterbrochenen Schreibvorgang ausgeschlossen ist.

Entweder wird die txg committed: Dann wurde ein neuer uberblock gebildet und das Dateisystem ist konsistent.

Oder die txg wurde nicht committed: Dann gilt der alte uberblock als aktuell und das Dateisystem ist ebenfalls konsistent (nur älter).

Der Schreibvorgang

Abb. 2: Nach einem Schreibvorgang werden die ersetzten Blöcke freigegeben. Die unveränderten Blöcke bleiben unberührt[2].

In Abbildung 2 ist der Zustand des Dateisystems nach einem Schreibvorgang mit Copy-on-Write zu sehen. Folgende Schritte haben zu diesem Ergebnis geführt:

  1. Eine Änderung macht es nötig, die Daten in Block D4 zu ersetzen
  2. Ein neuer Block D4' wird erstellt, welcher die neuen Daten enthält
  3. Der neue Block soll in den Hash-Baum eingebunden werden. Dazu ist es nötig, ein neues inode2 zu bilden, welches hier mit inode2' bezeichnet ist. Dieser Schritt ist notwendig, weil die Prüfsumme für alle übergeordneten Knoten neu gebildet werden muss
  4. Wie in Schritt 3 werden auch root und uberblock neu gebildet
  5. Die inner nodes werden mit den unveränderten Knoten neu verknüpft und die neuen Prüfsummen gebildet. Der neue Datenblock ist jetzt eingebunden

Durch die Einbindung des neuen Datenblocks wurden der alte Datenblock D4 genau wie alle übergeordneten Knoten ersetzt und freigegeben. Solange kein Snapshot den alten Block noch referenziert, kann dieser bei zukünftigen Schreibvorgängen wieder verwendet werden.

Konsequenzen der CoW-Strategie

Durch CoW ergeben sich einige der wichtigsten Funktionen von ZFS als logische Konsequenz. Allerdings ergeben sich so gleichermaßen auch einige der Schwächen von ZFS. Diese sind im Folgenden als Vorteile und Nachteile kurz gelistet.

Vorteile

  • Snapshots – also Momentaufnahmen eines Systemzustandes – lassen sich durch CoW einfach anlegen. Es muss lediglich der uberblock und seine darunterliegenden Knoten und Blöcke referenziert und eingefroren werden.
  • Klone sind ebenso einfach anzulegen, da auch hier mit einfachen Referenzierungen gearbeitet werden kann.
  • Inkrementelle Vervielfältigung ist genau, weil jeder Block ‚weiß', in welcher Transaktionsgruppe er entstanden ist. Dadurch kann ZFS beim Vergleich zweier Snapshots direkt zu den geänderten Stellen springen, statt jede Datei einzeln zu prüfen.
  • Datenkorruption ist nachverfolgbar und oft reparierbar. Durch die Nutzung von Prüfsummen können beschädigte Blöcke identifiziert werden. Hat man das Dateisystem redundant aufgebaut kann ein beschädigter Block in den meisten Fällen wiederhergestellt werden.
  • fsck ist obsolet, da CoW immer für einen konsistenten Pool sorgt.

Nachteile

  • Es entsteht Fragmentierung. Jede Änderung wird in neue Blöcke geschrieben. Dadurch fragmentieren selbst Dateien, die ursprünglich sequentiell geschrieben wurden. Je voller der zpool wird, desto schwieriger wird es außerdem, ausreichend zusammenhängende Blöcke für sequenzielle Schreibvorgänge zu finden.
  • Es wird zu jedem Zeitpunkt freier Speicherplatz benötigt, da selbst bei Löschvorgängen nicht die verwendeten Blöcke gelöscht, sondern neue Knoten und Blöcke angelegt werden müssen.
  • Sollen nur Teile eines Datensatzes geändert werden, kann das abhängig von der recordsize langsam sein, da immer der gesamte Datensatz gelesen werden muss. Bei einem Datensatz mit recordsize=128k , in dem 8 KB geändert werden sollen, müssen z.B. 128 KB gelesen, 8 KB im Speicher geändert und dann wieder als neuer Record mit 128 KB geschrieben werden.

Weitere Informationen

ZFS, Teil 1: Konzepte und Grundlagen von Michael Plura (heise.de, 2017)

Die Zeitmaschine im Kernel-Space: ZFS-Workflows unter Ubuntu 24.04 (linux-magazin.de, 2026)

"ZFS: the last word in file systems." by Jeff Bonwick (web.archive.org, 2026)

Quellen

  1. Merkle Tree (en.wikipedia.org, 2026)
  2. 2,0 2,1 Copy-on-Write in der OpenZFS Dokumentation (openzfs.github.io, 2026)


Autor: Stefan Bohn

Stefan Bohn ist seit 2020 bei der Thomas-Krenn.AG beschäftigt. Ursprünglich als Berater für IT-Lösungen im PreSales beheimatet, wechselte er 2022 zum Product Management. Dort widmet er sich dem Wissenstransfer und treibt dabei auch das Thomas-Krenn Wiki voran.

Das könnte Sie auch interessieren

ISCSI Grundlagen
ISCSI Performance Tuning