Ext4magic-Journal





Ext4magic: Inode - Directory - Journal - Installation - Zeit-Optionen - Tricks&Tipps - Manpage - Expert-Mode



Inhaltsverzeichnis

Das Filesytem Journal bei ext3 ext4

Das Filesystemjournal kann man sich vereinfacht vorstellen als eine Aufgabenbuch des Filesystem. Hier wird niedergeschrieben was am Filesystem verändert werden soll und zwar möglichst bevor oder unmittelbar bevor die Änderung am Filesystem selbst vorgenommen wird. Geschrieben wird hier unmittelbar auf die Platte. Ist die Änderung am Filesystem dann selbst erfolgt, dann wird im Aufgabenbuch diese Aktion als erledigt gekennzeichnet.



Der Zweck und die Funktionsaufgabe des Journals

Stürzt der Rechner während einer Schreiboperation aus irgend einem Grund ab, oder gibt es sonstige Probleme die das Betriebssystem hindern könnten einen Schreibauftrag wirklich fertig auf Platte zu schreiben, entsteht eventuell in den Filesystem Verwaltungsdaten halbfertige und noch nicht zusammen gehörende Daten. Die Folge: das Filesystem ist beschädigt und muss repariert werden. Bei ext2, welches noch kein Journal hat, dauert dieser Filesystemcheck ein ganze Weile, und die Dauer wächst mit Größe des Filesystems stetig mit. Nach einem Absturz müssen jetzt plötzlich mehrere große Filesysteme geprüft werden bevor sie wieder eingehängt und benutzt werden können. Der Bootvorgang verzögert sich dadurch um Minuten, Stunden ....

Bei einem Journalfilesystem erkennt der Filesystemcheck jetzt im Journal noch nicht erledigte Aufträge. Diese Aufträge werden jetzt einfach abgearbeitet, in dem die im Journal abgelegten Datenblöcke an die richtige Stelle im Filesystem kopiert werden. Damit wird das Filesystem wieder in sich konsistenten Status versetzt. Die Filesystem Verwaltungsdaten sind in sich schlüssig und passen zueinander. Das Filesystem kann so eingehängt und weiter betrieben werden. Der Einzelcheck des Filesystems dauert so nur Sekunden und der Rechner ist nach einem Absturz schnell wieder Betriebsbereit. Es ist durchaus möglich, dass die letzte Änderung des Dateiinhaltes verloren ist, aber das Filesystem ist ok. Gegen einen Verlust von Dateiinhalten oder Änderungen, die im Moment des Absturzes nur im Speicher existieren und noch nicht auf die Platte geschrieben wurden, sind wir sowieso nicht abgesichert.


Die Daten welche dabei ins Journal geschrieben werden, sind Kopien von den Filesystemverwaltungsdaten, also zB Inodeblöcke, Tabellen benutzer Inode und Filesystem Blöcke, aber auch die Verzeichnis Datenblöcke werden bei Veränderung vor dem schreiben ins richtige Filesystem dort erst einmal als Kopie abgelegt. Ein Journal kann extern auf einem anderem Blockdevice, zB. auf einer anderen Platte, betrieben werden. (Dieses wird von ext4magic unterstützt ist derzeit aber noch ungetestet), weit aus häufiger wird ein internes Journal betrieben. Dieses interne Journal ist eine nicht sichtbare Datei die eine feste Größe schon beim Anlegen des Filesystems zugeteilt bekommt. Die Größe richtet sich nach der Filesystemgröße und muss zwischen 1024 und 102400 Filesystemblocks sein. Diese Datei bekommt automatisch immer die Inode 8. (Es ist theoretisch möglich auch ein Journal mit einer anderen Inode zu betreiben, auch das ist in ext4magic berücksichtigt, ist jedoch derzeit deaktiviert, da es nur äußerst selten benötigt wird).

Eine typische und recht häufig anzutreffende Größe ist 128MByte für ein Journal eines mittelgroßen Filesystems bei einer Blockgröße von 4096 Byte. Das macht mkfs automatisch, wenn keine anders lautenden Optionen übergeben wurden. Wir gehen in der weiteren Betrachtung auf dieser Seite auch von dieser Größe aus.

Dieses Journal besteht nun aus einem kleinem Verwaltungskopf (1 oder 2 Blöcke groß) und die restlich Blöcke werden als Ringbuffer für die Journaldaten benutzt. Bei unserer Annahme für ein Filesystem mit einigen 'zig GByte Größe und 4KByte Blockgröße stehen also 32767 Filesystemblöcke für das Journal bereit. Wie das jetzt im Speziellen abläuft, ist zwar interessant, aber würde hier zu weit führen.



Erklärung Transaktion

Es werden je nach Menge der momentan anliegenden Änderungen eine gewisse Anzahl der zu schreibenden Filesystemblöcke zu einer Art virtuelles Paket zusammengepackt und der Reihe nach ins Journal geschrieben. Ein solches Paket nennt sich Transaktion und hat eine Ordnungsnummer. Der erste Block einer Transaktion erhält eine Tabelle "welcher Journalblock in dieser Transaktion hat eine Kopie von welchem Filesystemblock". Eine einzelne Transaktion kann eine einzige Kopie, aber auch viele Block Kopien umfassen, je nach dem wie viel sich gerade im Filesystem geändert hat.
ext4magic hat eine Funktion um sich den Inhalt der Journals nach Transaktionnummern anzeigen zu lassen.

 ROBI@LINUX:~ # ext4magic /dev/sda3 -T -x  | head -15
Filesystem in use: /dev/sda3

Using internal Journal at Inode 8

Found 24318 copy of Filesystemblock in Journal
FS-Block         Journal        Transact        Time in sec     Time of Transaction
      528253           2          160836        1274608139      Sun May 23 11:48:59 2010
      526364           3          160836        1274608142      Sun May 23 11:49:02 2010
      528252           4          160836        1274608144      Sun May 23 11:49:04 2010
      530214           5          160836        1274608139      Sun May 23 11:48:59 2010
      528644           6          160836        1274608143      Sun May 23 11:49:03 2010
      529252           7          160836        1274608139      Sun May 23 11:48:59 2010
      528109           8          160836        1274608139      Sun May 23 11:48:59 2010
      527224           9          160836        1274608139      Sun May 23 11:48:59 2010
      531243          10          160836        1274608139      Sun May 23 11:48:59 2010

Das wurde hier bewusst abgeschnitten, es sind also über 32000 Blöcke im Journal, die Ausgabe ist bei Block 10 ;-) Die Bedeutung der Spalten:

  1. Spalte : die Filesystem Blocknummer von der das eine Kopie darstellt

  2. Spalte : die Journalblocknummer in der sich diese Kopie befindet

  3. Spalte : die Transaktionnummer zu der diese Kopie gehört

  4. Spalte : (nur bei Inodeblöcken) den größten Zeitstempel aller im Block befindlicher Inode

  5. Spalte : die Zeit aus der vorherigen Spalte in einem anderem Format

Die Zeitangaben werden nur bei optionaler Verwendung der Option "-x" angezeigt.


Neben der Ausgabe für das komplette Journal können auch selektiv nur bestimmte Blöcke, bzw. nur Inodeblöcke die eine bestimmte Inode enthalten, zur Anzeige gebracht werden.

ROBI@LINUX:~ # ext4magic /dev/sda3 -T -x  -f etc/passwd
Filesystem in use: /dev/sda3

Using internal Journal at Inode 8
Inode found "etc/passwd"   565
Inode 565 is at group 0, block 1092, offset 1024

Transactions of Filesystemblock 1092 in Journal
FS-Block         Journal        Transact        Time in sec     Time of Transaction
        1092         534          160841        1274608166      Sun May 23 11:49:26 2010
        1092         611          160842        1274608168      Sun May 23 11:49:28 2010
        1092        9282          160664        1274559675      Sat May 22 22:21:15 2010
        1092        9468          160673        1274559723      Sat May 22 22:22:03 2010
        1092        9922          160716        1274560203      Sat May 22 22:30:03 2010
        1092       21004          140650        1272749403      Sat May  1 23:30:03 2010
        1092       21621          140659        1272749466      Sat May  1 23:31:06 2010
        1092       21697          140663        1272749467      Sat May  1 23:31:07 2010



Wieviel Daten passt in so ein Journal

Theoretisch bei angenommener Blockgröße 4 KB einer Journalgröße 128 MB und einer Inodegröße von 265 Byte würden dort bis zu 500000 Inode zu speichern sein. Ein Filesystem von 24 GB Größe mit den default Werten angelegt, hat jedoch schon die dreifache Menge an Inodes. Allerdings, Inode im Filesystem haben und Inodes auch alle benutzen, ist zweierlei. Die Anzahl der Dateien bestimmt letztlich wie viele Inode wirklich benutzt werden. Hinzu kommt noch, es werden nicht nur Inodeblöcke im Journal, sondern auch andere Verwaltungsblöcke des Filesystems abgelegt. Oftmals werden von einzelnen Inodeblöcken eine Vielzahl solcher Kopien entstehen, wenn zB fortlaufend dort Änderungen an einer dieser Inode erfolgen.





Welche Änderungen veranlassen das Anlegen einer Kopie eines Inodeblockes im Journal

Zum einen sind es wirklich die Änderungen an den Dateien und Verzeichnissen selbst. Oft ist der User nur mit der Bearbeitung einzelner Dateien am Rechner beschäftigt. Solche normale Änderungen, Neuanlegen, Löschen von Dateien erzeugen meist nur recht wenig Arbeit für das Filesystem. Erfolgt aber zB. ein Download einer sehr große Datei aus dem Internet, werden fortlaufend alle paar Sekunden Kopien von dem Inodeblock abgelegt, in dem sich diese Inode befindet. Werden ganze Verzeichnisbäume oder sehr viele Dateien verändert, dann werden auch relativ viele Inode Blöcke dort ins Journal kopiert.

Doch das ist noch längst nicht alles. Sind bei den Mountoptionen nicht "noatime" und "nodiratime" explizid gesetzt worden, greifen die default Optionen und es wird bei jedem Lesen eines Verzeichnisses und bei jedem Lesen einer Datei in der Inode die "atime" neu gesetzt. Zwar ändert das nicht die "ctime" der Inode, aber das Filesystem muss den Inodeblock beim nächsten sync neu auf Platte schreiben. Und beim neu Schreiben des Inodeblockes, werden wiederum Kopien davon ins Journal geschrieben.

Das hat Auswirkungen.
Durchsucht man zB mit find recurciv das ganze Filesystem, werden alle Inodeblöcke in denen sich Inode von Verzeichnissen befinden, ins Journal geschrieben. Erfolgt ein Vollbackup des Filesystems werden sogar von allen benutzten Inodeblöcken Kopien im Journal angefertigt. Aber auch automatische Dienste, welche regelmäßig das Filesystem durchlaufen um zB. die Dateien für Suchanfragen zu indizieren, hinterlassen im Journal ihre Spuren.

Es passt auf diese über 32000 Blöcke ja nun eine ganze Menge, wenn wir täglich nur unsere Mails bearbeiten, ein paar Dokumente lesen und im Internet surfen, reicht das eventuell über Tage. Wenn wir aber fortwährend mit grep rekursiv unser gesamtes Filesystem nach verschiedenen Stichworten durchsuchen, haben wir es eventuell auch schon in einer Stunde oder gar in wenigen Minuten geschafft.

Das Journal ist dann bis zum letztem Block vollgeschrieben. Da es wie ein Ringbuffer benutzt wird, werden die ältesten Kopien jetzt wieder mit den neuen überschrieben. Auch ein versehentlich Löschen von Dateien wird seine Kopien von gelöschten Inodes ins Journal schreiben. Zwar wird man dazwischen gelegentlich noch ein paar ungelöschte Inode finden, aber mit gelöschten Inodekopien kann ext4magic nichts anfangen, es braucht Kopien von ungelöschten Inodes. Diese Kopien welche beim Löschen ins Journal geschrieben werden, werden jedoch alte Blockkopien im Journal überschreiben. Eventuell werden dabei auch genau die alte Kopien überschrieben, die für einen erfolgreichen wieder herstellen der allerwichtigsten Dateien notwendig gewesen währen.

Bei einem rekursiven Löschen des Filesystems kommt es damit zwangsläufig zu einem "Überlauf" des Journalringbuffers wenn extrem viele Dateien gelöscht werden. Bei einem typischem Filesystem mit 256Byte Inodes, 4kB Blockgröße und 128MB Journalgröße wird dieses bei geschätzten mehr als 400000 Dateien auftreten die rekursiv gelöscht werden. Hierbei sinken auch die Chancen mit ext4magic dann noch möglichst viele der gelöschten Dateien wieder zu finden. Selbst die Magic-Funktion von ext4magic die Dateien aus den Datenblöcken recovern kann, nutzt Daten aus dem Journal und wird dann die zuerst gelöschten Dateien nicht mehr finden können, wenn durch einen Überlauf des Journalringbuffers der Beginn der Löschung im Journal überschrieben wurde.



kleines Beispiel mit ein paar Zahlen

Ein Test mit den Backup eines komplett neu installiertes OpenSuse mit über 100000 Dateien in über 6000 Verzeichnissen. Installations Größe über 3.5 GB. Getestet wurde auf einem 130 GB großes Filesystem, ext4, 4 KB Blockgröße und 128 MB Journal.



Löcher im Journal

Bis her sind wir hier immer davon ausgegangen, das Journal arbeitet als Ringbuffer und überschreibt sobald es voll ist seine ältesten Daten. Das stimmt aber nur zum Teil. Das stimmt nur so lange, wie das Filesystem gemountet bleibt. Wird das Filesystem umountet und anschließend wieder neu gemountet, dann schreibt es nicht dort weiter wo es vor dem umount aufgehört hat, sondern es beginnt das Journal von Anfang an neu zu überschreiben.

Am Beispiel

Wo ist der Unterschied.
Durch das neu mounten des Filesystems wird das Journal wieder von Anfang an beschrieben, und hat dadurch beim Löschen genau die Änderungen überschrieben, die am Anfang des Mountvorgang davor abgelaufen sind. Auf noch ältere Daten im Journal kann zugegriffen werden, aber dieser vorheriges Mount mit dem Anlegen der Dateien ist ein zeitliches Loch von dem keine Informationen zu finden sind.

Dieses wird noch dadurch verstärkt, das es ausreicht den Anfangsblock einer Transaktion zu überschreiben, um alle Kopien die zu dieser Transaktion gehören, unbrauchbar zu machen. Es währe nur mit einem riesengroßen Rechenaufwand überhaupt möglich, diesen Blöcken durch Auswertung ihres Inhaltes irgendwie wieder ihre richtige Blocknummer zuzuordnen. Bei großen Transaktionen können dadurch recht viele Blöcke unbrauchbar werden. Das Einspielen des Archiv aus dem Test von oben hat zB. beim recovern aller Dateien aus dem Backup nur 100 Transaktionsnummern verwendet.

Wird ein Rechner regelmäßig oder in kurzen Abständen rebootet, und während der Laufzeit des Rechners passiert auch in den Filesystemen nichts was größere Mengen an Daten im Journal hinterlässt, dann besteht das Journal manchmal am Anfang aus den aktuellen Daten, danach kommen nur noch Fragmente zwischen denen zT. größere zeitliche Löcher sind. Ganz am Ende können sich sogar noch uralte Journaldaten befinden. Sind zu viele kleine Einzelfragmente und zu große Löcher im Journal, wird dadurch die Kapazität für brauchbare zusammenhängende Informationen geringer, es fehlen ganze Zeitabschnitte dafür sind noch uralte Daten enthalten. ext4magic wird dann nicht alle Dateien und Verzeichnisse finden können.

Erkennen kann man solche Löcher aus dem Ablauf der Transaktionsnummern. Diese werden im Journal immer fortlaufend vergeben, auch über ein neu-Mounten hinweg. Ist mehr als ein Transaktionsnummern Sprung im Journal (einer kann mit dem Ringverhalten erklärt werden), dann ist dort ein Loch. Ein Blick auf die Ausgabe der Blocknummern von der "/etc/passwd" oben, zeigt zB. solche Löcher, die man hier schon an diesen wenigen Zeilen erkennt.

Ab den Versionen 0.2.4 / 0.3.0-pv2 wird versucht aus diesen Löchern auch noch Inodekopien für das Recover zu gewinnen. Derzeit ist es noch nicht möglich die ursprüngliche Inodenummer dieser Kopien zu ermitteln (Rechenaufwand zu groß), damit kann auch kein Dateiname und kein Löschzeitpunkt ermittelt werden. Erste Erfahrungen zeigen jedoch, das hier besonders auf Rechner die oft rebootet werden, eine ganze Menge aktuell gelöschter Dateien recoverbar werden.



Daraus folgt zwangsläufig

Im Journal befinden sich ständig größer Mengen an wertvollen Filesystemblock Kopien. Insbesondere von aktiven Bereichen im Filesystem, in denen man selbst oder das Betriebssystem ständig Dateien anfassen, wird man mit größerer Wahrscheinlichkeit immer ein oder mehrere Kopien der Inodeblöcke von vielen Dateien finden. Von Filesystemabschnitten die vergessen irgendwo auf der Platte liegen, in die auch schon lange niemand mehr reingeschaut hat, wird man eventuell gar keine Kopie einer Inode im Journal finden können. Tägliches oder regelmäßiges mounten in kurzen Zeitintervallen hinterlässt im Journal weniger brauchbare Informationen. Ab und zu mal ein paar wichtige Dateien oder Verzeichnisbäume anfassen, besser gleich ein Backup machen, erhöht auch die Wahrscheinlichkeit sie auch nach einem Unfall aus dem Filesystem selbst, wieder herstellen zu können.







Ext4magic: Inode - Directory - Journal - Installation - Zeit-Optionen - Tricks&Tipps - Manpage - Expert-Mode