URL dieses Artikels:

zu Ausgabe: 6.2006
ext3, Grundlagen und Tuning
Auf der Überholspur
Oliver Hamel
Das ext3 (Third Extended Filesystem) hat sich im Laufe der Jahre aufgrund seiner Stabilität, Erweiterbarkeit, Verbreitung und Einfachheit als quasi Standard-Dateisystem unter Linux etabliert. Im Folgenden möchte ich Ihnen am Beispiel der Entwicklung vom ext (Extended Filesystem) zum ext2 (Second Extended Filesystem) über das ext3 zum zukünftigen ext4 (Fourth Extended Filesystem) technische Details zu diesem beliebten Dateisystem erläutern. Nachdem Sie die Grundlagen des ext3 kennen gelernt haben, zeige ich Ihnen, wie Sie es an Ihre Ansprüche anpassen und somit die Performance und Zuverlässigkeit Ihres Servers oder Ihrer Workstation optimieren können.

Was ist ein Dateisystem? Das Dateisystem [1], im englischen Filesystem, dient dem Betriebssystem zur dauerhaften Ablage von Daten innerhalb eines hierarchischen Namensraumes. Spezielle Dateien, die Verzeichnisse, bilden Container, in denen Informationen in Form von Dateien strukturiert abgelegt werden. Über den Verzeichnispfad in Verbindung mit dem Dateinamen wird eine Datei direkt adressiert. Das Betriebssystem selbst ist ebenfalls im Dateisystem abgelegt.

Die Geschichte der ext-Familie
Linux wurde anfangs unter dem Minix-Betriebssystem [2] entwickelt. Der Einfachheit halber entschied sich Linus Torvalds, Linux vorerst mit dem Minix-Dateisystem auszustatten. Der Umfang des Minix-Dateisystems war jedoch zu limitiert, sodass nach kurzer Zeit die Arbeiten an einem neuen Dateisystem begannen. Um zukünftig das Hinzufügen von neuen Dateisystemen in den Linux-Kernel [3] zu erleichtern, wurde zuerst das Virtual Filesystem (VFS) als Schnittstelle entwickelt (Abbildung 1). Es behandelt System Calls, die mit dem Dateisystem agieren, und ruft die entsprechenden Funktionen auf, um zum Beispiel einen Schreibvorgang auf dem Massenspeicher umzusetzen. Nach der Integration des VFS in den Linux-Kernel wurde ext implementiert, welches den zukünftigen Ansprüchen wie bessere Performance und geringe Fragmentierung schnell nicht mehr genügte. ext2, welches aus ext hervorging und mit vielen Verbesserungen und Reorganisationen ausgestattet wurde, war viele Jahre der Standard für Dateisysteme unter Linux. Der Hauptnachteil von ext2 war, dass es kein Journaling-Dateisystem ist. Das ext3, welches unter anderem Journaling-Funktionen, einen H-Baum-Verzeichnisindex und eine Online-Veränderung der Dateisystemgröße mit sich bringt, setzt wiederum auf ext2 auf und ist abwärtskompatibel zu diesem. Das zukünftige, in der Entwicklung befindliche ext4 fügt weitere Optionen hinzu, die den wachsenden Ansprüchen an ein modernes Dateisystem gerecht werden sollen. Zu diesen zählen unter anderem: Verwaltung von bis zu 1 EByte (ExaByte, 10^18 Byte) Daten, variable Blockgrößen und eine dynamische Zuordnung von Inodes.


Das Virtual File System (VFS)

ext3-Grundlagen
ext3 verfolgt das Konzept der Unix-Dateisysteme, welche unter anderem aus Blöcken, Inodes und Verzeichnissen bestehen. Bei Bedarf können zusätzliche Eigenschaften (teilweise über das Einspielen von Patches) wie erweiterte Attribute, Kompression oder das Wiederherstellen gelöschter Dateien im Kernel aktiviert werden. Der Speicherplatz auf einem Datenträger, der mit ext3 formatiert ist, wird in Blöcke unterteilt, die unter den meisten Prozessorarchitekturen eine festgelegte Größe von 1 KB, 2 KB oder 4 KB haben und beim Erstellen des Dateisystems festgelegt werden. Die Blockgröße begrenzt die maximale Größe einer Datei und des gesamten Dateisystems. Um die nötigen Bewegungen des Festplattenkopfes gering zu halten und damit die Geschwindigkeit des Zugriffs zu beschleunigen, werden Blöcke in Gruppen zusammengefasst. Die Informationen zu den Blockgruppen werden in Deskriptortabellen direkt hinter dem Superblock gespeichert. Der Superblock, der am Anfang einer Partition liegt, enthält Details wie die Anzahl von Blöcken und Inodes sowie deren Belegung, wann das Dateisystem zum letzten Mal ein- oder ausgehängt wurde und weitere Informationen. Jedes Objekt im Dateisystem wird durch einen Inode (Indexknoten oder Indexeintrag) repräsentiert, in dem die Attribute wie zum Beispiel Dateityp, Zugriffsrechte, Besitzer, Timestamps und Zeiger auf die eigentlichen Datenblöcke der Datei hinterlegt sind. Der Inode wird über eine eindeutige Nummer für die Datei, die er verwaltet, identifiziert. Sie können sich den Inode als kleine Informationsdatei zu der eigentlichen Datei vorstellen. Ein Verzeichnis ist ein spezieller Dateityp, der eine Liste von Einträgen enthält. Jeder Eintrag verfügt über eine Inode-Nummer, einen Dateinamen und den Typ des Objektes (Datei, Verzeichnis, Symlink, Device, FIFO oder Socket). Eine Datei, die aus dem Inode und den Nutzdaten besteht, bezeichnet man auch als Link (Hard-Link). Mehrere Hard-Links können auf eine Datei verweisen. Im Inode wird die Anzahl der Links festgehalten, Sie können diese durch das Kommando ls -li anzeigen. Wird der letzte Link auf eine Datei gelöscht, so wird die Datei selbst durch die Freigabe des Inode und der Datenblöcke entfernt. Dies wird dadurch verdeutlicht, dass das Löschen einer Datei unter Linux durch den Systemcall unlink geschieht. Neben den Hard-Links gibt es im Dateisystem noch die symbolischen Links (Symlink). Sie enthalten einen Pfad- oder Dateinamen. Trifft der Kernel während der Auflösung eines Pfades (Pfadnamen zu Inodes) auf einen Symlink, wird der Name des Links durch den Inhalt ersetzt und eine neue Pfadnameninterpretation gestartet. Da ein Symlink nicht direkt auf einen Inode zeigt, kann er über Dateisystemgrenzen (mehrere Festplatten oder Partitionen) hinweg gesetzt werden. Es kann durchaus vorkommen, dass das Ziel eines Symlink gelöscht wurde und dieser dadurch ins Leere zeigt.
Es gibt noch weitere spezielle Dateien, die Devices (Gerätedateien) und FIFOs (First In – First Out). Eine Device-Datei belegt keinen Platz auf dem Massenspeicher, es ist im Grunde genommen ein Link auf den Gerätetreiber, der die Kommunikation mit der Hardware übernimmt. Hier wird zwischen Block- und Character-Device unterschieden. Devices werden über eine Major- (Gerätetyp) und Minor-Nummer (Einheit) identifiziert. Eine FIFO, im Englischen auch Pipe genannt, können Sie sich als ein Datenregister vorstellen, aus dem Elemente in genau der Reihenfolge abgerufen werden, in der sie zuvor abgelegt wurden.

mke2fs, tune2fs und e2fsck
Bevor wir beginnen, sollten wir uns mit den Programmen mke2fs, tune2fs und e2fsck aus dem Programmpaket e2fsprogs [4] vertraut machen. Für Details zu den drei Programmen konsolidieren Sie bitte die Manualpages mke2fs (8), tune2fs (8) und e2fsck (8). Mit mke2fs können Sie ein neues ext2- oder ext3- Dateisystem anlegen. mke2fs kennt viele Optionen, über die Sie zum Beispiel beim Anlegen die Blockgröße festlegen können. tune2fs dient dem Anzeigen und Anpassen von Parametern unter ext2 und ext3. Achten Sie darauf, dass Sie das Device entsprechend Ihrer Konfiguration anpassen. Um sich über tune2fs die aktuellen Einstellungen der Partition anzuzeigen, rufen Sie es mit folgenden Parametern auf: tune2fs –l /dev/[PARTITION]. Mit e2fsck können Sie ein ext2-Dateisystem überprüfen. Zusätzlich werden Dateisysteme mit einem Journaling (ext3) unterstützt, indem erst das Journal auf den Massenspeicher geschrieben und darauf der Vorgang wie unter ext2 umgesetzt wird. Es ist generell eine gute Idee, nach jeder Anpassung am Dateisystem eine Überprüfung mit e2fsck vorzunehmen. Dies verifiziert, dass das Dateisystem in Ordnung ist und Fehlerkorrekturen, falls nötig, durchgeführt werden. Achten Sie darauf, dass das Dateisystem nicht eingehängt (gemountet) ist, bevor Sie es mit mke2fs, tune2fs oder e2fsck modifizieren, es kann sonst ernsthaften Schaden nehmen und ist im schlimmsten Fall nicht mehr nutzbar! Es bietet sich an, von einer Live-CD wie zum Beispiel Knoppix [5] zu starten, um die Anpassungen aus dem laufenden Livesystem vorzunehmen.

Journaling-Stufen
Die Journalingerweiterung für ext2 (ext3) sorgt dafür, dass Metadaten auf dem Massenspeicher nicht mehr beschädigt werden können. Das Journal ist eine gewöhnliche Datei, in der die Metadaten festgehalten werden, bevor sie in die eigentliche Zieldatei geschrieben werden. Wird eine Änderung am Dateisystem vorgenommen, zum Beispiel durch das Anlegen einer Datei, so wird dies als Transaktion im Journal vermerkt. Eine Transaktion wird als abgeschlossen oder nicht abgeschlossen markiert. Ist eine Transaktion als abgeschlossen markiert, so ist garantiert, dass alle an dieser Transaktion beteiligten Vorgänge abgeschlossen sind und die an der Transaktion beteiligten Blöcke einen gültigen Status haben. Darauf werden die Informationen in das Dateisystem kopiert. Ist eine Transaktion zum Zeitpunkt eines Absturzes nicht als abgeschlossen markiert, so wird sie verworfen, da nicht garantiert werden kann, dass alle zugehörigen Blöcke konsistent sind. Ein Journal schützt also nicht davor, dass Daten (zum Beispiel bei einem Systemabsturz) verloren gehen. Es wird nur sichergestellt, dass ein konsistenter Datenbestand im Dateisystem besteht.
ext3 bietet die drei Journaling-Stufen Full, Writeback und Ordered, welche Einfluss auf die Geschwindigkeit, aber auch auf die Datenintegrität haben. Um die Journaling-Stufe festzulegen, müssen Sie die entsprechende Option in der Datei /etc/fstab setzen oder bei händisch eingebundenen Dateisystemen dem Befehl mount als Parameter übergeben.
  • Full (data=journal), wobei Metadaten und Inhalte erst in das Journal und darauf in das Dateisystem geschrieben werden. Der Vorteil besteht in der hohen Zuverlässigkeit, der Nachteil in verminderter Geschwindigkeit, da jeder Vorgang zweimal auf den Massenspeicher geschrieben wird.
  • Writeback (data=writeback), wobei nur die Metadaten in das Journal geschrieben werden. Der Vorteil ist die höhere Geschwindigkeit, der Nachteil ist die mögliche Datenkorruption durch abgebrochene Schreibvorgänge im Falle eines Absturzes.
  • Ordered (data=ordered) verhält sich wie die Option Writeback, wobei Dateiinhalte direkt in das Dateisystem geschrieben werden. Erst nach Abschluss des Vorganges werden die Metadaten im Journal aktualisiert. Ordered ist die Standardeinstellung unter Linux, da es Geschwindigkeit und Zuverlässigkeit vereint.

Reservierter Speicherplatz
Bei der Erstellung des Dateisystems wird in der Standardeinstellung fünf Prozent des Speicherplatzes für den Benutzer root reserviert. Dieser Reservespeicher ermöglicht es, selbst dann noch zu arbeiten, wenn das Dateisystem für alle anderen Benutzer bereits restlos belegt ist. Dämon-Prozesse zum Beispiel, wie der Syslogd, welcher unter der UID 0 läuft (root), können weiter Logfiles schreiben. Bei der Größe heutiger Festplatten stellt sich die Frage, ob eine Reserve von fünf Prozent nicht etwas hoch angesetzt ist. Beim anlegen des Dateisystems über mke2fs können Sie über den Schalter –m angeben, wie viel Prozent reserviert werden. Nachträglich können Sie diesen Wert auf einem bestehenden Dateisystem wieder mit dem Befehl tune2fs verändern.

Von ext2 zu ext3
Beim Aufsetzen eines neuen Server oder einer Workstation, haben Sie die Option, ext3 als Dateisystem zu verwenden. Sollten Sie ein älteres System mit ext2 in Betrieb haben, ist es ohne Weiteres möglich, das Dateisystem von ext2 zu ext3 zu konvertieren. Ich möchte auch hier noch einmal darauf hinweisen, dass jegliche Veränderung an den Optionen nur bei nicht eingehängtem Dateisystem vorgenommen werden müssen. Über den Aufruf tune2fs –j /dev/[PARTITION], wird die mit ext2 formatierte Partition zu ext3 konvertiert (das Journal hinzugefügt). Damit die konvertierte Partition zukünftig auch als ext3 eingebunden wird, muss der entsprechende Eintrag in der Datei /etc/fstab von ext2 auf auto geändert werden. Dies hat den Vorteil, dass der Kernel das Dateisystem automatisch erkennt und auch einbinden kann, wenn er ext3 nicht unterstützt. In diesem Fall wird das Dateisystem einfach weiterhin als ext2, natürlich ohne Journaling-Funktionalität, eingebunden.

Langatmige Dateisystem-Checks
Auch wenn wir nun über ein Journaling-Dateisystem verfügen, ist es weiterhin sinnvoll, dass es in regelmäßigen Abständen überprüft wird, um zum Beispiel Probleme mit der Hardware zu erkennen. Es gibt zwei Zähler, anhand derer festgelegt wird, wie oft ein Dateisystem überprüft wird. Der so genannte "Maximal mount count" und das "Check interval". Auch diese Parameter können wir über tune2fs –l /dev/[PARTITION] auslesen und entsprechend unseren Ansprüchen über die Optionen –c max-mount-counts, -C mount-count und –i interval-between-checks setzen oder bei Bedarf deaktivieren. Für Laptops, die häufig booten, können Sie zum Beispiel hohe Werte für den maximalen Mount-Zähler wählen.

Verzeichnis Indexierung
ext3 verfügt über einen zusätzlichen H-Baum-Verzeichnisindex (hashed b-tree Indexing), der eine hohe Performance bei Zugriffen auf Verzeichnisse mit vielen Dateien ermöglicht (wie zum Beispiel bei einem Mail- oder Fileserver). Sie können diese Indexierung aktivieren, indem Sie -O dir_index beim Erstellen des Dateisystems zum mke2fs-Befehl hinzufügen. Alternativ können Sie diese Option auch nachträglich auf einem bereits bestehenden Dateisystem anwenden, indem Sie tune2fs mit der Option –O dir_index und dem entsprechenden Device aufrufen (am Beispiel: tune2fs -O dir_index /dev/[PARTITION]). Alle Verzeichnisse, die nach dem Aufruf auf diesem Device erstellt werden, verfügen über die Indexierung. Um bereits bestehende Verzeichnisse einzubeziehen, rufen Sie nachträglich noch e2fsck zum Reindizieren auf (am Beispiel: e2fsck –D /dev/[PARTITION]). Haben Sie etwas Geduld, das Reindizieren dauert auf manchen Systemen etwas länger. Über den Aufruf tune2fs –l /dev/[PARTITION] überprüfen wir nachträglich, ob unter dem Punkt "Filesystem Features" die Option "dir_index" aufgeführt ist.

Mount-Optionen
Es gibt verschiedene Mount-Optionen, welche die Performance des Dateisystems positiv beeinflussen können. In diesem Kontext möchte ich besonders die beiden folgenden betrachten. Jede Mount-Option können Sie explizit für jeden Mountpoint in der Datei /etc/fstab setzen.
  • noatime: Bei jedem Zugriff auf eine Datei wird im Inode die Zugriffszeit gespeichert. Wenn Sie die Zugriffszeit nicht benötigen, können Sie über die Option noatime verhindern, dass diese in den Inode geschrieben wird und sparen somit eine Menge Schreibzugriffe im Dateisystem.
  • commit=N: In der Standardeinstellung werden Meta- und Nutzerdaten alle 5 Sekunden aus den Puffern auf die Festplatte geschrieben. Der Wert ist so niedrig angesetzt, weil die ext3-Entwickler sehr hohen Wert auf die Sicherheit der Daten legen. Auch hier ist mit einer höheren Einstellung ein Plus an Performance herauszuholen, wobei darauf zu achten ist, dass die Puffer in regelmäßigen Abständen geleert werden, da es sonst zu einem übermäßigen Gebrauch von Arbeitsspeicher und eventuellem Swappen (Auslagern von Inhalten aus dem Arbeitsspeicher auf die Festplatte) kommen kann.

Performance-Messung
In den folgenden Beispielen wurde jeweils über mkfs.ext3 ein neues Dateisystem mit einer Größe von 1024 MB auf /dev/hdc1 angelegt. Listing 1 zeigt, wie das Dateisystem mit der Journaling-Stufe Full eingebunden wird. Darauf wird das aktuelle Kernelarchiv in dieses Verzeichnis kopiert und die benötigte Zeit für das Extrahieren mit tar und bzip2 gemessen.

# mount -o data=journal /dev/hdc1 /mnt/
# cd /mnt/
# cp /home/linux-2.6.17.13.tar.bz2 .
# sync
# time tar xfj linux-2.6.17.13.tar.bz2

real 0m58.297s
user 0m36.410s
sys 0m4.084s

Im zweiten Beispiel (Listing 2) wird nach dem Formatieren ein Verzeichnis Index angelegt. Darauf wird das Dateisystem mit der Journaling-Stufe Writeback und den zusätzlichen Mount-Optionen noatime und commit=120 eingebunden. Auch hier wird wieder die Zeit für das Extrahieren des Kernelarchives mit tar und bzip2 gemessen. Das Ergebnis kann sich sehen lassen. Knapp 15 Sekunden Unterschied bei einem komprimierten Archiv von ca. 40 MB. Dieser Benchmark erhebt keinen Anspruch auf Genauigkeit. Für genauere Ergebnisse können Sie zum Beispiel die Benchmark-Suite Bonnie++ [8] benutzen.

# tune2fs –O dir_index /dev/hdc1
# mount -o data=writeback,noatime,commit=120 /dev/hdc1 /mnt/
# cd /mnt/
# cp /home/linux-2.6.17.13.tar.bz2 .
# sync
# time tar xfj linux-2.6.17.13.tar.bz2

real 0m43.703s
user 0m36.574s
sys 0m4.248s

Erweiterte Attribute
ext3 unterstützt zusätzlich zu den Standardattributen zehn weitere, die mit lsattr angezeigt und mit chattr gesetzt werden können. Erweiterte Attribute auf einem Verzeichnis werden an neu erzeugte, darunter liegende Dateien vererbt. Nützlich ist zum Beispiel das „A“, welches das Updaten der Atime deaktiviert oder das „i“, welches das Ändern oder Löschen der Datei unterbindet. Eine Übersicht finden Sie in der Manualpage chattr (1).

Nachteile von ext3
Ein Nachteil von ext3 ist die statische Zuordnung der Inodes (das in der Entwicklung befindliche ext4 schafft hier Abhilfe). Beim Anlegen des Dateisystems wird die Anzahl der Inodes festgelegt. Sind keine Inodes mehr frei, kann keine neue Datei mehr angelegt werden. Egal, wie viel Speicherplatz noch auf dem Medium vorhanden ist. In der Regel werden Sie aber diese Zahl nicht überschreiten. Anzeigen können Sie sich die Anzahl wieder mit tune2fs –l (in der Ausgabe unter dem Punkt "Inode count"). Sollte Ihnen die Standardeinstellung doch nicht genügen, können Sie die Anzahl der reservierten Inodes beim Anlegen des Dateisystems mit mke2fs über die Option –N festlegen.

Fazit
ext3 präsentiert sich als gestandener Allrounder mit Anpassungsmöglichkeiten. Für spezielle Einsatzzwecke macht es Sinn, zusätzlich die Möglichkeiten anderer Dateisysteme wie zum Beispiel ReiserFS, xfs, jfs oder das neue zfs (wird gerade auf Linux portiert) zu betrachten. Jedes Dateisystem hat seine Stärken und Schwächen und sollte den Ansprüchen entsprechend ausgewählt werden. Mein persönlicher Favorit ist nach wie vor ext3, nicht zuletzt, weil ich noch nie schlechte Erfahrungen damit gemacht habe.

© 2004 Software & Support Verlag GmbH. Vervielfältigung nur mit Genehmigung des Verlags. Fragen?