Die meisten Datenrettungen, über die wir berichten, passen auf eine Werkbank. Diese hier füllte ein ganzes Rack.
Ein Kunde, der einen BeeGFS-Cluster mit drei Nodes betreibt, wandte sich an uns, nachdem eines seiner Storage-Targets Dateien nicht mehr korrekt bereitstellte. Jeder Node enthält rund 489 TB Chunk-Daten auf einem RAID-6-Verbund mit 32 Laufwerken. Zwei Nodes waren intakt. Der dritte war „repariert“ worden, und genau diese Reparatur führte zu diesem Fall.
Ein IT-Techniker führte in bester Absicht eine Dateisystemprüfung auf dem XFS-Volume durch, das dem Chunk-Speicher zugrunde liegt. xfs_repair tat genau das, wofür es entwickelt wurde. Wenn es Verzeichniseinträge findet, die sich nicht validieren lassen, trennt es die betroffenen Objekte ab und verschiebt sie nach lost+found, damit sich das Dateisystem anschließend wieder sauber einhängen lässt. Das funktionierte. Das Dateisystem ließ sich mounten. 82.547.185 Dateien landeten unter lost+found in rund 1,84 Millionen nummerierten Unterverzeichnissen. Ihre Dateinamen waren noch vorhanden, ihre ursprünglichen Pfade jedoch nicht.
Für BeeGFS existiert ein Chunk nicht mehr, sobald sich sein Pfad geändert hat. Der Cluster meldete mehrere Petabyte an intakter Kapazität, konnte jedoch auf einen großen Teil davon nicht mehr zugreifen.
Im Folgenden zeigen wir, wie wir die Daten zurückholten, welche Werkzeuge wir dafür entwickeln mussten und welche Erkenntnisse dabei besonders wichtig waren. Mehrfach stellte sich unsere eigene Rekonstruktion als falsch heraus. Entscheidend war, dass wir diese Fehler erkannten, bevor sie Auswirkungen auf die Daten des Kunden hatten.
Warum der Pfad Teil der Daten ist
Es ist wichtig, genau zu verstehen, warum das Verschieben von Dateien nach lost+found bei einem Cluster-Dateisystem katastrophal sein kann, während es bei einem gewöhnlichen Dateisystem meist nur ein lösbares Problem darstellt.
Auf einem normalen Linux-Server ist eine Datei, die mit intaktem Inhalt in lost+found wiederhergestellt wurde, zwar lästig, aber nicht verloren. Ein Benutzer kann sie öffnen, identifizieren und an ihren ursprünglichen Ort zurückverschieben. Die Bedeutung steckt im Inhalt.
Bei BeeGFS funktioniert das anders. Die Metadatenserver verwalten den Namespace und damit die Verzeichnisstruktur, die Benutzer sehen. Die Storage-Targets speichern dagegen nur die eigentlichen Chunks. Die Identität eines Chunks wird vollständig durch seinen Speicherort bestimmt:
chunks/u<uid>/<hash1>/<hash2>/<parentEntryID>/<entryID>
Der Metadatenserver berechnet diesen Pfad anhand der Dateiattribute und fordert den Chunk exakt an dieser Stelle vom Storage-Target an. Es gibt keine Suche, keinen Fallback und keine Inhaltsprüfung. Befindet sich der Chunk nicht am berechneten Pfad, gilt die Datei für den Cluster als nicht vorhanden. Das gilt selbst dann, wenn die Daten nur wenige Verzeichnisse entfernt vollständig und unbeschädigt auf dem Datenträger liegen.
xfs_repair hatte also 100 % der Daten erhalten, gleichzeitig aber 100 % ihrer Nutzbarkeit zerstört. Jedes Byte war noch vorhanden. Lesbar war trotzdem nichts.
Diese Unterscheidung bestimmte den gesamten weiteren Verlauf. Wir mussten nicht die Daten selbst wiederherstellen. Die Daten waren intakt. Wir mussten ihre Adressen rekonstruieren.
Sprechen Sie noch heute mit unseren Datenrettungsspezialisten.
Schritt null: Nichts wird verändert, bevor alles kopiert ist
Bevor auch nur ein einziger Befehl auf der Hardware des Kunden ausgeführt wurde, erstellten wir von jedem Laufwerk des beschädigten Nodes ein identisches Abbild. 32 Quelllaufwerke, 32 Ziellaufwerke, Sektor für Sektor.
Bei einem Fall dieser Größenordnung ist das keine Formalität. Jede der unten beschriebenen Methoden ist ein Experiment, und mehrere davon scheiterten beim ersten Versuch. Eine bytegenaue Kopie des ursprünglichen Volumes sorgt dafür, dass ein fehlgeschlagenes Experiment nur einige Stunden Arbeit kostet und nicht zu einem dauerhaften Datenverlust führt.
Dadurch stand uns später auch der Zustand vor der Reparatur noch zur Verfügung, als wir das Raw-Volume nach gelöschten Strukturen durchsuchen mussten. Dieser Punkt wurde in Phase 3, mehrere Monate nach Beginn des Projekts, entscheidend, obwohl das am ersten Tag niemand vorhersehen konnte.
Es gibt noch einen zweiten Grund, der weniger offensichtlich, aber genauso wichtig ist. Sobald ein Image vorhanden ist, kann man deutlich offensiver arbeiten. Datenrettung wird sehr langsam, wenn jeder Befehl das Risiko birgt, die Situation zu verschlimmern. Ingenieure beginnen dann, jeden Schritt mehrfach zu hinterfragen, zusätzliche Prüfungen durchzuführen und Experimente zu vermeiden, die eine Frage eigentlich in zehn Minuten beantworten könnten.
Mit einem verifizierten Image im Hintergrund ändert sich diese Abwägung. Man kann auch etwas ausprobieren, das wahrscheinlich nicht funktioniert, weil die Folgen eines Fehlers begrenzt sind.
Wenn Sie sich nur einen Punkt aus diesem Artikel merken, dann diesen: zuerst ein Image erstellen, danach diagnostizieren. Einer der teuersten Fehler bei der Datenrettung in Unternehmensumgebungen ist es, ein Reparaturtool auf der einzigen vorhandenen Kopie auszuführen.
Die Wiederherstellung einer Umgebung dieser Größenordnung erforderte einen sorgfältig kontrollierten Prozess zur Server-Datenrettung, damit die ursprünglichen Datenträger unverändert erhalten blieben, während wir die Speicherstruktur rekonstruierten.
Manuelle Rekonstruktion eines 500-TB-RAID-6
Die 32 Laufwerke waren 18-TB-Enterprise-Festplatten von Seagate mit jeweils 16,37 TiB nutzbarer Kapazität. Eine kommerzielle Recovery-Software erkannte das Array automatisch und zeigte ein Volume mit einer XFS-Partition ab Sektor 2048. Das war vielversprechend, doch bei dieser Größe kam die GUI kaum weiter. Scans blieben hängen, Prozesse liefen nicht durch, Fortschrittsanzeigen sprangen nach einem Tag zurück. Wir brauchten direkten, skriptfähigen Zugriff auf das zusammengesetzte Volume.
Also entwickelten wir einen eigenen Userspace-RAID-6-Mapper.
Die erkannten Parameter wirkten zunächst eindeutig: Left-Symmetric-Layout, 256-KB-Stripe-Unit, Parity Delay 1, P zuerst und Q danach, Galois-Field-Polynom 0x11d. Auch die Laufwerksreihenfolge im RAID-Panel stimmte. Trotzdem war das resultierende Volume falsch.
Die Ursache lag im Rotationsursprung. Bei Stripe 0 liegt P in diesem Array auf Position 30 und Q auf Position 31. Die Daten beginnen ab P+2. Bei Linux md liegt P im Left-Symmetric-Layout dagegen auf Position 31. Beide Varianten sind intern korrekt, zählen die Rotation aber von unterschiedlichen Ausgangspunkten. Die Korrektur ist eine Verschiebung um eine Position: rotation_shift = 1. Alternativ lässt sich die Laufwerksreihenfolge um eine Position nach rechts drehen und der Shift auf null lassen. Beide Varianten ergeben dieselbe Zuordnung.
Solche Details können bei Trial-and-Error Tage kosten, weil eine fast korrekte RAID-Zuordnung zunächst plausibel aussieht. Partitionstabellen lassen sich lesen, der erste Superblock wirkt sauber und Verzeichnisse erscheinen. Erst tiefer im Volume zerfällt alles in Datenrauschen. Bis dahin kann bereits viel Analyse auf einer falschen Grundlage basieren.
Bevor wir der Zuordnung vertrauten, bestätigten wir sie zweimal unabhängig voneinander:
Wir lasen zufällig verteilte Stripes über das gesamte Volume, berechneten für jedes mögliche Layout die P- und Q-Syndrome und prüften, welche Variante konsistent war. Nur eine bestand den Test: 60 von 60 Stripes korrekt für P und 60 von 60 für Q.
Alle anderen Layouts scheiterten bei der Mehrheit der Stripes. Der Test ist besonders aussagekräftig, weil P und Q unterschiedlich berechnet werden. P basiert auf einem einfachen XOR, während Q eine gewichtete Summe im Galois-Feld verwendet. Ein Layout, das zufällig einen der beiden Tests besteht, wird daher fast nie auch den anderen bestehen.
Wir nahmen ein kleines Referenz-Image aus der kommerziellen Software und verglichen 256-KB-Blöcke der Rohdatenlaufwerke anhand ihres Inhalts damit. Das Ergebnis war identisch, diesmal ganz ohne Paritätsberechnung.
Dann folgte der entscheidende Beweis. XFS schreibt am Anfang jeder Allocation Group einen Superblock. Dieses Volume hat 492 davon, gleichmäßig über die gesamten 540 TB verteilt. Jeder sekundäre Superblock enthält dieselbe UUID, Blockgröße, AG-Größe und Gesamtzahl der Blöcke wie der primäre. Ist die RAID-Geometrie auch nur um eine Position falsch, liegen die sekundären Superblöcke an der falschen Stelle und lassen sich nicht mehr korrekt lesen.
Wir prüften acht davon, verteilt bis zur 536-TB-Marke. Alle acht ließen sich korrekt lesen und lieferten dieselben Werte: 4-KB-Blöcke, 492 Allocation Groups und eine einheitliche UUID. Damit war die Blockzuordnung über die gesamte Größe des Arrays verifiziert, nicht nur über die ersten Gigabyte.
Diesen Test führen wir inzwischen vor jeder Rekonstruktion eines großen Arrays durch und empfehlen ihn auch anderen. Dateisysteme wie XFS, ext4 und ZFS verteilen redundante Metadaten über das gesamte Volume und liefern damit praktische Prüfpunkte für die RAID-Geometrie. Nutzen Sie sie. Eine RAID-Zuordnung, die nur am Anfang des Volumes geprüft wurde, ist nicht wirklich verifiziert.
Die tatsächliche Volume-Größe beträgt 539.969.999.339.520 Byte. Das entspricht 540,0 TB dezimal oder 491,1 TiB. Dieser Unterschied ist entscheidend, wenn externer Speicher für das Image dimensioniert werden muss, und führte bereits vor Projektbeginn zu einer konkreten Beschaffungsfrage.
Das Ausmaß des Problems
Nachdem das Array wieder zusammengesetzt und lesbar war, konnten wir den Schaden erstmals vollständig erfassen. Ein Verzeichnislisting des Storage-Roots zeigte das Ausmaß:
Zwei Zahlen fallen sofort auf. Das Verzeichnis lost+found hat einen Link Count von 1.843.952, also rund 1,84 Millionen Unterverzeichnisse. Der Verzeichnis-Inode selbst ist 514 MB groß. Das ist kein Dateisystem im Normalzustand.
Bemerkenswert ist auch das leere Verzeichnis buddymir. BeeGFS unterstützt Buddy Mirroring und speichert dabei eine zweite Kopie jedes Chunks auf einem Partner-Target. In diesem Cluster war die Funktion zwar konfiguriert, wurde aber nicht genutzt. Drei Nodes Infrastruktur, aber nur eine Kopie der Daten. Darauf kommen wir später zurück.
Ein Scan des Volumes in eine Datenbank lieferte die genaue Zahl: 82.547.185 Dateien unter lost+found, bei einem Dateisystem, das insgesamt rund 147 Millionen enthalten sollte.
Sprechen Sie noch heute mit unseren Datenrettungsspezialisten.
Die Tool-Entscheidung, die alles Weitere möglich machte
Bevor wir die einzelnen Phasen beschreiben, lohnt sich ein Blick auf eine Entscheidung, die den gesamten Ablauf prägte: Fast die komplette Analyse führten wir mit DuckDB durch.
Bei mehreren zehn Millionen Pfadeinträgen kommt man mit Shell-Skripten nicht weit. Naive Ansätze scheitern schnell an der Join-Performance. Die erste Version unseres Relocation-Skripts exportierte für jeweils 200 Dateien die komplette Routenliste neu und scannte zusätzlich eine stetig wachsende Logdatei. Das war ein O(N²)-Ansatz, der bei diesem Datenbestand Wochen gedauert hätte. Entdeckt haben wir das nur, weil wir ihn vorher mit einem synthetischen Datensatz getestet hatten.
Eine spaltenorientierte Analyse-Engine, die lokal läuft, Parquet direkt liest und problemlos Hunderte Millionen Zeilen verknüpft, machte aus einer Woche Skriptarbeit einige SQL-Abfragen. Konkret führten wir im Verlauf der Recovery unter anderem folgende Joins aus:
- 43 Millionen rekonstruierte Routen mit 408 Millionen Metadatensätzen
- 39 Millionen Dateien ohne Route mit 278 Millionen Entry-IDs gesunder Nodes
- 1,1 Millionen Scanner-Ergebnisse mit 99 Millionen aktiven Dateisystemeinträgen
Jeder dieser Joins lief auf einer einzelnen Workstation in wenigen Minuten. Als Skript wäre keiner davon praktikabel gewesen.
Der größere Punkt ist: Datenrettung in dieser Größenordnung ist im Kern ein Data-Engineering-Problem mit Storage-Engineering-Fassade. Die eigentliche Schwierigkeit besteht nicht darin, Bytes von einem Datenträger zu lesen. Sie besteht darin, Millionen von Fakten aus vier unabhängigen Quellen zusammenzuführen und zu entscheiden, welcher Quelle man vertraut, wenn sie sich widersprechen. Genau das wurde zur zentralen Frage des gesamten Projekts.
Phase 1: Das Reparaturlog rückwärts lesen
xfs_repair protokolliert sehr detailliert, was beim Abtrennen von Objekten passiert. Dieses Log ist damit praktisch eine teilweise Aufzeichnung der früheren Verzeichnisstruktur.
Wir analysierten die Ausgabe und rekonstruierten daraus zwei Dinge: den ursprünglichen Pfad jedes verwaisten Objekts sowie die Parent-Child-Beziehungen zwischen den Verzeichnissen. Diese Daten kamen zusammen mit einem vollständigen Scan des aktuellen Dateisystemzustands in DuckDB. Insgesamt umfassten die drei Datenbanken rund 10 GB.
Die Routing-Logik verknüpfte drei Abfragen:
Der erste Routing-Durchlauf lieferte Zielpfade für 43.222.159 Dateien. Dann entdeckten wir das strukturelle Muster, das den weiteren Verlauf deutlich vereinfachte:
xfs_repair verschob ganze Verzeichnisse, nicht einzelne Dateien.
Dadurch haben der physische Pfad unter lost+found/<inode>/… und der rekonstruierte Zielpfad denselben Suffix:
source /brick/storage/lost+found/302914319544/4/1A70-691C4D29-1/323F-691C4D56-2
└────────── suffix ─────────────┘
target /brick/storage/chunks/u80D/691C /4/1A70-691C4D29-1/323F-691C4D56-2
Bei der Prüfung folgten 42.870.846 von 43.222.159 Routen diesem Muster, also 99,19 %. Die übrigen 351.313 waren verschachtelte Dateien, deren Basename übereinstimmte, deren direktes Parent-Verzeichnis jedoch abwich. Kein Zufall, sondern ein klar erklärbarer Widerspruch zwischen zwei Quellen.
Diese Übereinstimmung nutzten wir als Filter. Für den ersten Verschiebevorgang exportierten wir nur Routen, bei denen Rekonstruktion und physische Daten übereinstimmten. Die 351.313 strittigen Fälle ließen wir vollständig zurück. Damals wirkte das lediglich vorsichtig. Später erwies sich diese Entscheidung als eine der wichtigsten im gesamten Projekt.
Die Wiederherstellung der bestätigten Dateien dauerte 1 Stunde und 10 Minuten für 42,87 Millionen Dateien, bei rund 10.000 Dateien pro Sekunde, zwei Konflikten und keinen Fehlern.
So funktioniert der Mover
Einige Details zur Funktionsweise sind bei dieser Größenordnung entscheidend.
Verschoben wird immer mit link() + unlink(), nie per Kopie. Ein Hardlink mit anschließendem Entfernen der Quelle entspricht praktisch einem Rename: gleicher Inode, keine Daten werden gelesen oder geschrieben, Besitzer, Rechte, Zeitstempel und Extended Attributes bleiben erhalten. Wichtig ist auch die Atomarität. link() schlägt mit EEXIST fehl, wenn das Ziel bereits belegt ist. Ein vorhandener Chunk kann also nicht unbemerkt überschrieben werden. mv -n wirkt ähnlich, führt aber erst ein stat und dann ein rename aus. Dadurch bleibt ein Zeitfenster, in dem konkurrierende Schreibvorgänge verloren gehen können.
Jeder Move wird vor dem nächsten Batch in einem Ledger protokolliert. Dadurch bleibt der gesamte Vorgang reversibel. Ein Rollback-Skript liest das Ledger, vertauscht Quelle und Ziel und stellt alles wieder zurück. Bei einem Projekt dieser Größe ist ein Undo-Pfad unverzichtbar. In einem Testdatensatz bestätigten wir, dass der Verzeichnisbaum vor und nach einem vollständigen Move-und-Rollback-Zyklus denselben Hash hatte.
Der Mover liest nur eine flache Routenliste. Keine Datenbank, keine Locks, keine Abfrage pro Datei. Der Fortschritt wird als Byte-Offset in dieser Datei gespeichert. Nach einem Abbruch setzt der Lauf höchstens 20.000 Routen vor der letzten Position wieder an, ein Crash kostet damit nur Sekunden.
Worker-Prozesse führen Syscalls aus, keine Forks. Die erste Version startete für jede Datei mkdir, ln und rm, also drei Prozesse für jede der 42 Millionen Dateien. Gemessene Leistung: 215 Dateien pro Sekunde. Python-Worker mit direkten Aufrufen von os.link() und os.unlink() verkürzten denselben Test von 4 Minuten 38 Sekunden auf 3 Sekunden. Das entspricht einer 130-fachen Beschleunigung, allein durch den Verzicht auf Prozessstarts.
Tests auf der realen Hardware zeigten, dass 32 Worker deutlich schneller waren als 8, während 64 wieder langsamer wurden. Ab einem gewissen Punkt konkurrieren die Prozesse nur noch um das XFS-Log und Verzeichnis-Locks. Deshalb lohnt es sich, zu messen statt zu raten.
Schnelle Bearbeitungszeiten für geschäftskritische Daten
Phase 2: Reverse Engineering der BeeGFS-Inode-Tabelle
Phase 1 deckte die Dateien ab, die im Reparaturlog erfasst waren. Rund 39 Millionen blieben übrig. Dafür brauchten wir eine andere verlässliche Quelle, und BeeGFS selbst lieferte sie: die eigenen Metadaten.
Der Kunde hatte eine Woche vor der Reparatur beegfs-fsck ausgeführt. Dabei wurde die Sicht der Metadatenserver auf das Dateisystem in mehrere kompakte Binärtabellen geschrieben. Die für uns relevante Tabelle fileinodes war 45,7 GB groß. Da ihr Format nicht veröffentlicht ist, dekodierten wir sie manuell anhand von Hex-Dumps.
Die Struktur bestand aus einem 4.176-Byte-Header, gefolgt von festen Datensätzen mit jeweils 112 Byte. Für uns waren darin folgende Felder relevant:
Aus diesen Feldern lässt sich der Chunk-Pfad direkt ableiten:
chunks/u{uid:X}/{parent-timestamp hex[0:4]}/{parent-timestamp hex[4]}/{parentEntryID}/{entryID}
Bevor wir der Formel vertrauten, prüften wir sie anhand realer Pfade aus dem Dateisystem des Kunden. Dazu gehörten auch die beiden Pfade, die in Phase 1 als Konflikte aufgetreten waren. Beide wurden exakt reproduziert.
BeeGFS-Umgebungen umfassen häufig große und komplexe Speicherkonfigurationen. Mehr erfahren Sie über professionelle RAID-Datenrettung.
Dreimal falsch gelegen
Der Parser funktionierte nicht auf Anhieb. Gerade die Art, wie er scheiterte, war jedoch besonders lehrreich. Wir ließen ihn bei jedem nicht validierbaren Datensatz abbrechen, statt fehlerhafte Records einfach zu überspringen. So entdeckten wir drei unterschiedliche Fehler, die sonst in großem Maßstab plausible, aber falsche Ergebnisse erzeugt hätten.
- Fehler eins: Ein Flags-Feld wurde für eine Signatur gehalten. Den u32-Wert bei +28 hatten wir als konstantes 0x20000623 interpretiert und als Record-Marker verwendet. In der echten Datei scheiterten 6,46 % der Datensätze daran. Die Analyse zeigte 0x20000622, nur ein Bit Unterschied, bei ansonsten vollständig gültigen Daten. Es war ein Flags-Feld, keine Signatur. Beide Varianten waren legitim.
- Fehler zwei: Null gesetzte Parent-Felder. Einige Records enthalten im Parent-Feld 0-0-0 und speichern den tatsächlichen Parent im Feld für den ursprünglichen Parent. Unsere Formel hätte daraus unbemerkt Pfade wie chunks/u7D1/0/0/0-0-0/… erzeugt. Genau solche stillen, plausiblen Fehler sind besonders gefährlich. Entdeckt haben wir sie nur, weil wir den Parser zuerst auf einem 200-MB-Ausschnitt testeten und die Verteilung prüften.
- Fehler drei: Variable Stripe-Breite. Nach den ersten beiden Korrekturen brach ein Worker weiterhin ab: 18 fehlerhafte Records unter 50,9 Millionen, an einem korrekt ausgerichteten Offset. Im Hex-Dump stand 0x20000423 statt 0x20000623, dazu eine Stripe-Target-Liste mit zwei statt drei Einträgen. Byte +29 war also kein Teil einer Signatur, sondern die Länge der Stripe-Target-Liste. Diese 18 Dateien waren nur über zwei der drei Targets gestriped und vollständig gültig.
Alle drei Fehler fanden wir mit derselben Methode: alles validieren, bei Abweichungen abbrechen, die Ursache analysieren und erst dann die Regel erweitern. Hätten wir nicht lesbare Records einfach übersprungen, wäre ein scheinbar vollständiger Datensatz entstanden, dem stillschweigend Millionen Einträge gefehlt hätten.
Der finale Parse umfasste 407.833.733 Records in einer 6,3-GB-Parquet-Datei. Jeder einzelne bestand die Validierung. Wir speicherten nur Integer-Werte und erzeugten die Pfade erst bei der Abfrage, da vollständig materialisierte Pfadstrings die Dateigröße ohne Nutzen etwa verdreifacht hätten.
Vertrauen Sie den Experten mit nachgewiesenen Ergebnissen
Dann kam der Abgleich mit der Realität
Hier wurde das Projekt besonders interessant.
Wir hatten nun zwei unabhängige Rekonstruktionen: die aus dem Reparaturlog aus Phase 1 und die Inode-Tabelle aus Phase 2. Bei 765.220 Dateien widersprachen sie sich. Naheliegend wäre gewesen, der vermeintlich zuverlässigeren Quelle zu folgen. Doch wir wussten nicht, welche das war.
Die Lösung lieferten die beiden anderen Nodes des Kunden.
Da Dateien auf allen drei Targets unter demselben relativen Pfad gestriped werden, lag die korrekte Verzeichnisstruktur des beschädigten Nodes auf brick001 und brick002 noch vollständig vor. Wir baten das Kundenteam um ein Listing. Stattdessen erhielten wir vollständige Scans mit Dateigrößen, Zeitstempeln in Mikrosekundenauflösung und Inode-Nummern, jeweils als eigene Datenbank pro Node.
Zusammen ergaben sie 10.972.742 reale Chunk-Verzeichnisse und 277.743.284 eindeutige Entry-IDs. Es gab keinerlei Mehrdeutigkeit: Auf keinem der beiden Nodes war eine Entry-ID zwei verschiedenen Verzeichnissen zugeordnet.
Bevor wir diese Daten als Referenz verwendeten, führten wir einen Kontrolltest durch. Wir nahmen 196.510 Zuordnungen, bei denen beide Rekonstruktionen bereits übereinstimmten, und prüften, ob die entsprechenden Verzeichnisse auf den gesunden Nodes existierten:
196.510 von 196.510. 100,00 %.
Dieses Ergebnis war die Grundlage für alles Weitere. Es zeigte, dass die Verzeichnisdaten der gesunden Nodes praktisch keine Lücken enthielten. Fehlte dort ein Verzeichnis, war es also tatsächlich kein gültiges BeeGFS-Verzeichnis und nicht nur das Ergebnis eines unvollständigen Scans.
Dann führten wir denselben Test mit den 414.896 strittigen Dateien durch:
Die Inode-Tabelle verlor. Mehr als die Hälfte der vorgeschlagenen Parent-Verzeichnisse existierte auf keinem funktionierenden Dateisystem.
Das war das Gegenteil unserer Erwartung. Wir hatten die Inode-Tabelle selbst reverse-engineert, die Pfadformel mit realen Daten validiert und gesehen, dass sie in einer anderen Teilmenge 350.281-mal mit den physischen Daten übereinstimmte, bei nur 990 Abweichungen. Wir vertrauten ihr. Die gesunden Nodes zeigten jedoch etwas anderes, und sie waren keine Rekonstruktion.
Bei genauerer Analyse wurde der Grund klar: Alle 414.896 Fälle waren einzelne Dateien direkt unter lost+found/<inode>/, ohne erhaltenes Parent-Verzeichnis. Für solche Dateien enthielt die Inode-Tabelle keine verlässliche Parent-Information, erzeugte aber trotzdem einen Wert. Bei verschachtelten Dateien mit erhaltenem Parent-Verzeichnis war sie dagegen zuverlässig.
Daraus folgten zwei Erkenntnisse. Erstens waren die 42,87 Millionen Dateien aus Phase 1 korrekt platziert und mussten nicht zurückgesetzt werden. Zweitens kann eine Quelle für eine bestimmte Datenpopulation zuverlässig und für eine andere unzuverlässig sein. Gesamtgenauigkeiten verschleiern diesen Unterschied. Hätten wir die Inode-Tabelle pauschal nach ihrer Gesamtgenauigkeit bewertet, wären 414.896 Dateien in Verzeichnisse verschoben worden, die gar nicht existieren.
Die 351.313 zurückgehaltenen Dateien
Die strittigen Dateien aus Phase 1 prüften wir auf dieselbe Weise. Von den 111.858 Fällen, die sich mit den Referenzdaten abgleichen ließen, waren:
- Rekonstruktion aus dem Reparaturlog: 0 korrekt. Kein einziger.
- Inode-Tabelle: 111.590 korrekt, also 99,76 %.
Die Entscheidung, diese Dateien vor dem ersten Verschiebevorgang zurückzuhalten, war also richtig und ließ sich nun eindeutig belegen. In Phase 2 wurden sie anhand der Inode-Tabelle korrekt zugeordnet.
Genauigkeit messen statt voraussetzen
Von den 20,3 Millionen verschachtelten Dateien, die Phase 1 nicht zuordnen konnte, hatten 5.327.469 ein Gegenstück auf einem gesunden Node. Damit konnten wir die Ergebnisse der Inode-Tabelle direkt mit den Referenzdaten vergleichen.
5.285.754 von 5.326.860 korrekt. 99,23 %.
Diese Zahl machte Phase 2 belastbar. Keine Annahme, sondern eine Messung an mehr als fünf Millionen Dateien auf einem funktionierenden Dateisystem, genau für die Daten, die wir verschieben wollten.
Die 0,78 % Fehler waren nicht zufällig verteilt, sondern konzentriert: 41.106 Fehler stammten aus nur 8.863 falschen Verzeichnissen. Allein die größte fehlerhafte Zuordnung betraf 7.496 Dateien. Die Inode-Tabelle scheiterte also pro Parent-Record, nicht pro Datei. Daraus ergaben sich zwei Sicherheitsfilter:
- Das vorgeschlagene Parent-Verzeichnis musste auf einem gesunden Node existieren. Damit wurden 30.863 der 41.106 bekannten Fehler erkannt, also 75 %.
- Das vorgeschlagene Parent-Verzeichnis durfte nicht auf einer Blockliste mit 8.863 nachweislich falschen Verzeichnissen stehen.
Zusammen reduzierten diese Filter die erwartete Fehlerrate von 0,78 % auf etwa 0,19 %.
Phase 2: Durchführung
Der Verschiebevorgang lief bewusst in zwei getrennten Stufen, damit wir zunächst die verlässlichere Gruppe prüfen konnten:
- Stufe 1, Referenzdaten: Dateien, deren korrekter Pfad direkt von einem funktionierenden Dateisystem übernommen wurde. Keine Rekonstruktion nötig. 5.439.318 Dateien, 9 Konflikte, 23 Min. 42 Sek.
- Stufe 2, Inode-Tabelle mit beiden Filtern: 14.522.074 Dateien, 13 Konflikte, 40 Min. 44 Sek.
Auch die Konfliktraten sind aussagekräftig: 9 bei 5,4 Millionen und 13 bei 14,5 Millionen Dateien. Hätte die Inode-Tabelle viele Dateien falsch zugeordnet, wären deutlich mehr falsche Zielpfade mit bereits korrekt platzierten Dateien kollidiert. Die Ausführung bestätigte also unsere Messungen.
Zwischenstand: 62.832.238 von 82.547.185 Dateien wiederhergestellt, also 76 %.
Übrig blieben 19.013.790 Dateien, die direkt in lost+found lagen und elfstellige Namen ohne Bindestriche hatten. xfs_repair hatte sie nach ihrer Inode-Nummer umbenannt. Ihre Entry-IDs, also der einzige Schlüssel zwischen Chunk und Datei, waren verloren. Hinzu kamen 701.135 bewusst zurückgehaltene Dateien, für die sich kein belastbarer Zielpfad bestimmen ließ: 659.655 mit einem Parent-Verzeichnis, das auf keinem gesunden Node existierte, 36.209 auf der Blockliste und 5.271, die in der Inode-Tabelle vollständig fehlten.
Bei Kundendaten raten wir nicht. Eine Datei am falschen Ort ist schlimmer als eine Datei in lost+found, weil sie korrekt aussieht.
Was Striping für die Datenrettung tatsächlich bedeutet
Während Phase 2 erwähnte der Kunde ein Detail, das einen Teil unserer Analyse neu einordnete: Er hatte einer Chunk-Datei die Endung .jpg angehängt, und sie ließ sich als vollständiges Bild öffnen.
Das dürfte eigentlich nicht passieren, wenn Chunks nur Fragmente sind. Es passiert jedoch, wenn eine Datei klein genug ist, um vollständig in einen einzelnen 512-KB-Chunk zu passen. Dann liegt die gesamte Datei auf einem Target, und der erste Chunk enthält bereits den Dateikopf.
Ein Vergleich desselben Verzeichnisses auf allen drei Nodes machte dieses Muster deutlich:
Auf jedem Node erscheinen dieselben Dateinamen. Der Chunk-Name entspricht der Entry-ID der Datei und gehört damit zur Datei selbst, nicht zum jeweiligen Target. Die Größen unterscheiden sich, weil jedes Target andere Byte-Bereiche enthält. Außerdem gibt es Lücken, weil kleine Dateien nur auf einem einzelnen Target liegen.
2.097.152 entspricht exakt 4 × 512 KB und 1.572.864 genau 3 × 512 KB, also jeweils vollständigen Stripes. Die ungeraden Werte sind Restdaten.
Damit erklärte sich eine Abweichung, die uns bereits beschäftigt hatte. Von den nicht zugeordneten verschachtelten Dateien tauchten 26,2 % auch auf gesunden Nodes auf. Bei den Dateien aus Phase 1 waren es dagegen nur 2,8 %. Fast ein zehnfacher Unterschied zwischen zwei Gruppen derselben Festplatte.
Die Ursache war die Dateigröße. Verschachtelte Dateien waren im Durchschnitt 8,49 MB groß, die lose abgelegten nur 1,62 MB. Eine Datei landet erst dann auf einem zweiten Target, wenn sie größer als ein Chunk ist. Größere Dateien haben daher zwangsläufig häufiger ein Gegenstück auf einem anderen Node. Keine der beiden Messungen war falsch. Wir hatten lediglich zwei Gruppen mit unterschiedlichem Striping-Verhalten verglichen und den Unterschied zunächst überinterpretiert.
Es ist nur ein kleines Detail. Genau solche Details führen jedoch schnell zu überzeugend klingenden, aber falschen Schlussfolgerungen.
Die praktische Konsequenz
Eine gestripe-te Datei benötigt die Chunks aller Targets. 62,8 Millionen wiederhergestellte Chunks bedeuten also nicht automatisch 62,8 Millionen lesbare Dateien. Lesbar ist nur eine Datei, deren sämtliche Chunks wieder vorhanden sind. Fehlt auch nur ein Teil, bleibt sie beschädigt.
Dafür entwickelten wir ein kleines Tool. Aus Dateigröße, Chunk-Größe und Anzahl der Targets berechnet es die erwartete Datenmenge pro Target und vergleicht sie mit den tatsächlich vorhandenen Werten.
file size : 5242880 bytes (5.00 MB)
stripe count : 10
expected bytes per target:
target 0 : 2097152 (4 stripes)
target 1 : 1572864 (3 stripes)
target 2 : 1572864 (3 stripes)
observed vs expected:
target 0 : observed 2097152 expected 2097152 match
target 1 : observed 1572864 expected 1572864 match
target 2 : observed 0 expected 1572864 DIFFERS
MISSING 1572864 bytes (30.0% of the file)
Die Anzahl der Chunks zeigt den Fortschritt der Datenrettung. Dieses Tool zeigt dagegen den Zustand der eigentlichen Datei, und genau das ist für den Kunden entscheidend.
Phase 3: Die 150 TB, die nicht da waren
Nachdem die Verzeichnisstruktur weitgehend wiederhergestellt war, verglichen wir die Kapazität der drei Nodes. Die beiden gesunden Nodes waren nahezu identisch:
Bei der Datenmenge lagen sie nur 0,002 % auseinander, bei der Dateizahl 0,020 %. BeeGFS hatte die Daten nahezu perfekt gleichmäßig verteilt. Damit eignete sich jeder der beiden Nodes sehr gut als Referenz dafür, was der dritte enthalten sollte.
Der reparierte Node nach beiden Phasen:
Rund 30 % des Targets waren schlicht verschwunden. Die Daten lagen weder in chunks/ noch in lost+found/, und es gab keinerlei Dateisystemeintrag mehr dafür.
Die durchschnittliche Größe der fehlenden Dateien lag bei 2,97 MB, gegenüber 3,17 MB auf den gesunden Nodes. Das ist nah genug, um von einem repräsentativen Querschnitt auszugehen und nicht von einer bestimmten Dateiklasse. Es waren also nicht nur große Dateien betroffen oder ein einzelnes Benutzerverzeichnis verschwunden.
Wohin waren die Daten verschwunden? Sehr wahrscheinlich durch eine Kombination aus dem Lauf von xfs_repair und früheren Wiederherstellungsversuchen des Kunden. Blöcke wurden freigegeben, Metadaten verworfen und Teile davon später überschrieben. Genau deshalb ist der Rat, weitere Reparaturversuche zu stoppen und professionelle Hilfe zu holen, mehr als nur Marketing. Mit jedem gut gemeinten Eingriff sinkt der noch wiederherstellbare Anteil.
Auf dem Datenträger liegt mehr, als das Dateisystem noch erkennt
Ein Teilscan des ursprünglichen Images, etwa 5 % des Volumes, fand 1.111.960 Dateien in den Rohstrukturen. Davon:
- 202.009 waren im aktiven Dateisystem vorhanden, mit 100,00 % Übereinstimmung bei der Dateigröße. Damit waren sowohl der Scanner als auch die Join-Methode vollständig validiert.
- 909.951 existierten weder in chunks/ noch in lost+found/. Zusammen knapp 2 TB. Das Dateisystem konnte sie nicht mehr sehen, der Datenträger enthielt sie jedoch weiterhin.
Dann kam die entscheidende Frage für Phase 3: Können wir bestimmen, wohin diese Dateien gehören?
840.479 von 909.951, also 92,37 %, haben einen berechenbaren Zielpfad aus der Inode-Tabelle. Davon besitzen 833.264, also 99,14 %, ein Parent-Verzeichnis, das auf einem gesunden Node existiert.
Diese Zahlen fassen das gesamte Recovery-Modell zusammen. Die Dateien haben keinen Verzeichniseintrag, keinen Pfad und keinen sichtbaren Dateisystemeintrag mehr. Trotzdem können wir 92 % davon zuordnen, weil die Metadatenserver die Parent-Beziehung unabhängig von XFS gespeichert haben und wir sie mit einem funktionierenden Dateisystem abgleichen können.
Hochgerechnet auf das gesamte Volume ergibt die 5-%-Stichprobe rund 18 Millionen Dateien und 40 TB. Das entspricht etwa 38 % der fehlenden Dateien und 27 % des fehlenden Volumens. Ob sich auch der Rest wiederherstellen lässt, hängt davon ab, wie repräsentativ dieses Scanfenster war. Genau das prüfen wir weiter, statt darüber zu spekulieren.
Entwicklung eines XFS-Scanners für ein halbes Petabyte
Das Problem in Phase 3 war, dass keines unserer vorhandenen Tools dafür geeignet war. Kommerzielle Recovery-Software stößt bei einem XFS-Volume mit einem halben Petabyte an ihre Grenzen. xfs_db ist ein Debugger, kein Scanner. Und ein einfacher Brute-Force-Scan von 540 TB würde bei üblichem Durchsatz mehrere Wochen dauern, ohne währenddessen verwertbare Teilergebnisse zu liefern.
Also entwickelten wir einen eigenen Scanner.
Das Tool liest XFS v4 und v5 direkt aus einem Raw-Image oder Blockgerät. Es mountet nichts, schreibt nie auf die Quelle und verfügt über zwei unabhängige Methoden, um sämtliche Inodes zu finden. Bei einem beschädigten Volume kann man schließlich nicht davon ausgehen, dass die Metadatenbäume zuverlässig sind.
Der Scanner arbeitet bewusst in drei getrennten Durchläufen.
Durchlauf 1: Inode-B+tree (schnell)
Jede Allocation Group besitzt einen Inode-B+tree, der genau festhält, welche Inode-Chunks belegt sind. Wenn man diesen Baum durchläuft und nur die referenzierten Blöcke liest, rekonstruiert man den aktiven Namespace anhand der Inode-Daten statt des gesamten Volumes. Bei einem 540-TB-Dateisystem bedeutet das einige Hundert Gigabyte Lesezugriffe statt 540 Terabyte. Stunden statt Wochen.
Durchlauf 2: Verzeichnisblöcke in physischer Reihenfolge lesen
Hier erzielten wir den größten Geschwindigkeitsgewinn, nicht durch schnelleres Lesen, sondern durch weniger zufällige Zugriffe.
Der naheliegende Weg wäre, den Verzeichnisbaum rekursiv zu durchlaufen. Bei rotierenden Festplatten und Millionen Verzeichnissen führt das jedoch zu massivem Random I/O.
Deshalb liest Durchlauf 1 keine Verzeichnisblöcke, sondern speichert nur deren Positionen. Durchlauf 2 sammelt anschließend alle Offsets, sortiert sie nach ihrer physischen Lage und liest sie sequenziell. XFS v5 speichert die Inode-Nummer des Besitzers direkt im Header des Verzeichnisblocks. Dadurch lässt sich jeder Block seinem Inode zuordnen, ohne die Baumstruktur zu benötigen.
Gleiche Daten, gleiches Ergebnis. Sequenziell statt zufällig, typischerweise 10- bis 50-mal schneller.
Durchlauf 3: Raw-Scan nur im freien Speicher
Die Durchläufe 1 und 2 rekonstruieren, was das Dateisystem noch kennt. Durchlauf 3 sucht nach dem Rest: gelöschten Inodes, verwaisten Verzeichnisblöcken und Dateinamen, die in ungenutzten Bereichen aktiver Verzeichnisblöcke erhalten geblieben sind.
Wird eine Datei aus einem XFS-Verzeichnis gelöscht, wird ihr Eintrag als ungenutzt markiert, die Bytes selbst aber nicht entfernt. Inode-Nummer und Dateiname bleiben meist lesbar, bis sie überschrieben werden. Unser Parser durchsucht diese ungenutzten Bereiche und extrahiert die verbliebenen Daten. So erhält eine gelöschte Datei ihren Namen zurück, statt nur als nummerierter Datenblock wiederhergestellt zu werden. In diesem Fall entscheidet das darüber, ob ein Chunk zugeordnet werden kann oder anonym bleibt.
Ein Raw-Scan ist aufwendig, deshalb haben wir ihn gezielt eingeschränkt. Vor dem Scan liest das Tool den Free-Space-B+tree und ermittelt exakt die Byte-Bereiche, die keiner Datei zugeordnet sind. Gelöschte Metadaten können definitionsgemäß nur dort liegen. Dadurch reduzierte sich der Aufwand auf diesem Volume ungefähr um den Faktor drei. Das Tool zeigt das Verhältnis vor dem Start an, sodass klar ist, ob der Scan eher acht Stunden oder drei Tage dauern wird.
Die Lesezugriffe selbst beschleunigen
Die Arbeit wird auf mehrere Prozesse verteilt, jeweils mit eigenem File Descriptor. Dadurch blockiert nichts an einem gemeinsam genutzten Handle.
Gelesen wird in 64-MiB-Blöcken und, wo verfügbar, mit O_DIRECT. Es bringt nichts, den Page Cache mit einem halben Petabyte Daten zu füllen, die nur einmal gelesen werden.
Physisch benachbarte Inode-Chunks werden zu größeren Lesezugriffen zusammengefasst.
Der Magic-Number-Test prüft mit einem vektorisierten Stride-Vergleich nur ein Byte pro 512 Byte. Kandidaten lassen sich so nahezu ohne Zusatzaufwand erkennen. Vollständig geparst werden nur Treffer.
XFS-v5-Inodes speichern ihre eigene Inode-Nummer und die UUID des Dateisystems. Der Abgleich mit der Fundposition reduziert False Positives nahezu auf null. Das ist entscheidend, wenn über Billionen Byte-Offsets nach Mustern gesucht wird.
Die Ausgabe wird in Row Groups direkt auf den Datenträger geschrieben, statt im Speicher gesammelt zu werden. Unsere erste Version puffertete den gesamten Bereich jedes Workers und wurde auf einem 32-GB-System vom OOM-Reaper beendet. Die Streaming-Version benötigt unabhängig von der Volume-Größe konstanten Speicher.
Alle Ergebnisse werden in geshardetem Parquet- oder TSV-Format gespeichert und lassen sich ohne Import direkt in DuckDB laden.
Was wir aus diesem Fall lernen können
Führen Sie kein Reparaturtool direkt auf dem zugrunde liegenden Speicher eines verteilten Dateisystems aus. xfs_repair hat nichts falsch gemacht. Es erledigte seine Aufgabe korrekt, und das Dateisystem ließ sich anschließend sauber mounten. Ein BeeGFS-Chunk-Store ist jedoch kein gewöhnliches Dateisystem. Der Pfad ist Teil der Datenidentität. Ein Tool, das Dateiinhalte erhält, aber Pfade verwirft, bewahrt für BeeGFS nichts Nutzbares. Bei einem Cluster-Dateisystem sollte die Reparatur mit den dafür vorgesehenen Cluster-Tools erfolgen. Wenn diese nicht weiterhelfen, ist das der Moment aufzuhören und nicht auf eine tiefere Ebene auszuweichen.
Striping ohne Mirroring ist ein Single Point of Failure mit zusätzlichen Schritten. In diesem Cluster waren die Dateien über alle drei Targets gestriped, während Buddy Mirroring deaktiviert war. Die buddymir-Verzeichnisse waren leer. Damit war jede Datei mit einem Chunk auf dem beschädigten Node unlesbar, solange dieser ausfiel, unabhängig vom Zustand der anderen beiden. Drei Instanzen der Infrastruktur, aber nur eine Kopie der Daten. Das sollte bei jeder BeeGFS-Umgebung geprüft werden. Mirroring lässt sich leicht auf später verschieben, kann dann aber teuer werden.
Skalierung verändert nicht nur die Dauer, sondern auch die geeigneten Werkzeuge. Bei 10 TB sind viele der hier beschriebenen Methoden Standard. Bei 540 TB hängt die GUI, rekursive Scans laufen nicht durch und Brute-Force-Scans dauern Wochen. Datenrettung im Petabyte-Bereich wird damit zu einem Data-Engineering-Problem: spaltenorientierte Datenbanken, sequenzielles I/O, parallele Verarbeitung und Ergebnisse, die schrittweise verfügbar werden.
Verifizieren Sie die RAID-Geometrie über das gesamte Volume. Eine Zuordnung, die am Anfang korrekt und am Ende falsch ist, kann Wochen kosten. XFS liefert hier 492 über das Array verteilte Prüfpunkte. Nutzen Sie sie.
Bei Abweichungen abbrechen, nicht überspringen. Unser Binärparser schrieb keine Ausgabe, sobald ein Datensatz nicht validiert werden konnte. Dadurch entdeckten wir drei unterschiedliche Fehlinterpretationen des Formats, die sonst Millionen plausibler, aber falscher Ergebnisse erzeugt hätten. Ein Parser, der Unbekanntes einfach überspringt, kann unbemerkt falsche Sicherheit erzeugen.
Quellen erst gegen reale Referenzdaten prüfen, dann vertrauen. Unsere beiden Rekonstruktionen widersprachen sich bei 765.220 Dateien. Erst die gesunden Nodes lieferten eine belastbare Antwort, und zwar gegen die Quelle, der wir selbst zunächst eher vertraut hatten. Alle weiteren Entscheidungen basierten deshalb auf gemessener Genauigkeit für genau die jeweilige Datenpopulation.
Gesamtgenauigkeit kann populationsspezifische Fehler verdecken. Dieselbe Inode-Tabelle war bei verschachtelten Dateien zu 99,23 % korrekt, bei lose abgelegten Dateien aber nur zu 46 %. Eine einzige Gesamtzahl wäre irreführend gewesen. Validierung sollte deshalb nach Datengruppen getrennt erfolgen.
Machen Sie jeden Schritt reversibel und testen Sie den Rollback. Jeder Move wurde in einem Ledger protokolliert, und das Rollback-Skript wurde mit vollständigen Move-und-Undo-Zyklen getestet. Bei 20 Millionen Dateien erkennt man systematische Fehler nicht durch Sichtprüfung. Man kann aber sicherstellen, dass sie sich später ohne weiteren Schaden korrigieren lassen.
Die Arbeit geht weiter
Zum Zeitpunkt dieses Artikels sind 62,8 Millionen von 82,5 Millionen Dateien wieder an ihrem richtigen Platz. Parallel läuft der vollständige Scan des Volumes nach den fehlenden 149,62 TB. Schwieriger sind die verbleibenden losen Dateien, deren Namen durch Inode-Nummern ersetzt wurden. Hier bietet der Raw-Scan die beste Chance, gelöschte Verzeichniseinträge aus dem freien Speicher auszulesen und so die ursprünglichen Dateinamen zurückzugewinnen.
Ob am Ende nahezu 490 TB wiederhergestellt werden können oder weniger, hängt davon ab, wie viel der fehlenden Kapazität nur abgetrennt und wie viel tatsächlich überschrieben wurde. Das wird der vollständige Scan zeigen. Bereits jetzt wissen wir jedoch, dass sich für 92 % der im ersten Sample gefundenen verwaisten Dateien ein Zielpfad berechnen lässt. Die Grenze dieser Recovery wird damit vor allem durch bereits überschriebene Daten bestimmt, nicht durch die Frage, wohin die Dateien gehören.
Probleme mit einem großen Speichersystem?
RAID Data Recovery Services übernimmt die Wiederherstellung von Enterprise-RAID-, NAS-, SAN- und verteilten Dateisystemen jeder Größenordnung. Dazu gehören auch Fälle, in denen bereits Standardtools eingesetzt wurden und die Situation verschlimmert haben. Wenn Ihr Array beschädigt ist, sollten Sie Schreibzugriffe sofort stoppen und online Hilfe anfordern oder uns anrufen, bevor ein weiterer Reparaturversuch gestartet wird.
Die Kundendaten in diesem Artikel wurden anonymisiert. Seriennummern der Laufwerke, Hostnamen und identifizierende Konfigurationsdetails wurden weggelassen.
Häufig gestellte Fragen
Warum waren die Dateien nach dem Verschieben nach lost+found nicht mehr zugänglich?
BeeGFS-Storage-Targets enthalten Chunk-Dateien, deren Speicherort Teil ihrer Identität ist. Die Metadatenserver erwarten jeden Chunk an einem bestimmten Pfad, der aus Attributen wie User-ID, Parent-Entry-ID und Entry-ID berechnet wird. Selbst wenn die Chunk-Daten vollständig intakt sind, kann BeeGFS sie nicht verwenden, wenn die Datei nicht mehr am erwarteten Pfad liegt.
Wie viele Dateien waren betroffen?
Die Recovery identifizierte 82.547.185 Dateien unter lost+found. Nach den ersten beiden großen Wiederherstellungsphasen waren 62,8 Millionen Dateien wieder an belastbaren Zielpfaden platziert. Das entspricht rund 76 % dieses Bestands.
Wie können gelöschte Dateien unter XFS trotzdem wiederhergestellt werden?
Beim Löschen werden Dateisystemreferenzen häufig entfernt, bevor die zugrunde liegenden Daten überschrieben werden. Der in dieser Fallstudie beschriebene Scanner durchsucht Inode-Strukturen, Verzeichnisblöcke, ungenutzte Bereiche von Verzeichniseinträgen und ausgewählte freie Speicherbereiche nach Restdaten, mit denen sich Dateien und ihre ursprünglichen Namen noch identifizieren lassen.
Was sollte ich tun, wenn mein BeeGFS-Storage-Target online ist, aber Dateien fehlen?
Stoppen Sie unnötige Schreibzugriffe und führen Sie xfs_repair nicht erneut aus. Ein BeeGFS-Target kann online sein, obwohl Dateien weiterhin unzugänglich sind, weil ihre Chunk-Pfade verändert wurden oder verloren gegangen sind. Sichern Sie zuerst die Laufwerke und führen Sie die Diagnose anschließend anhand eines Images durch.