Ext4magic: Inode - Directory - Journal - Installation - Zeit-Optionen - Tricks&Tipps - Manpage - Expert-Mode |
Inhaltsverzeichnis |
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.
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.
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:
Spalte : die Filesystem Blocknummer von der das eine Kopie darstellt
Spalte : die Journalblocknummer in der sich diese Kopie befindet
Spalte : die Transaktionnummer zu der diese Kopie gehört
Spalte : (nur bei Inodeblöcken) den größten Zeitstempel aller im Block befindlicher Inode
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
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.
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.
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.
Das komplette Backup des neu installierten OpenSuse in das neu angelegte Filesystem recovern, das hat am Ende 98% vom Journal belegt, hat also mit allen Inodeblöcken und allen Verzeichnisblöcken und allem anderen Metadaten des Filesystems dort genau hinein gepasst.
Ein anschließender rekursiver "find" durch das ganze Filesystem, hat fast 10% der Kapazität des Journals benötigt und somit einen Teil der Journaldaten am Anfang des Journals überschrieben (geschrieben wurden dabei alle Inodeblöcke die Verzeichnis Inodes enthalten haben).
Ein komplettes Backup dieses Filesystems nach /dev/null hat weitere 30% des Journals überschrieben, (das waren alle benutzten Inodeblöcke).
Ein anschließendes rekursives löschen hat noch einmal 30% des Journals überschrieben. (Da hierbei die Verzeichnisblöcke alle ungültig geworden sind, brauchten diese nicht mit in Journal kopiert zu werden, es wurden hier also hauptsächlich auch nur die Inodeblöcke im Journal abgelegt)
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
Wir mounten ein Filesystem neu. Dort legen wir ein Verzeichnis an und erzeugen darin ein paar 100 Dateien. Danach führen wir einen sync aus, oder machen eine kleine Pause, damit Linux die Zeit hat die Änderungen im Filesystembuffer von sich aus auch sicher auf Platte zu schreiben. Danach löschen wir das vorhin erzeugte Verzeichnis mit all den Dateien die wir darin angelegt haben.
ext4magic kann jetzt von all diesen gelöschten Daten problemlos Kopien anfertigen.
Haben wir allerdings keine Pause gemacht, sondern haben uns gedacht, wenn wir das Filesystem umounten wird der Filesystembuffer auch sauber auf Platte geschrieben. Also umounten wir, um anschließend das Filesystem wieder neu zu mounten. Jetzt werde wir nach dem löschen der Dateien feststellen dürfen, es kann nur noch einen kleinen Teil dieser Dateien wahrscheinlich aber gar keine mehr mit ext4magic recovert werden.
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.
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 |