BTRFS: Auffinden und Reparieren stark fragmentierter Dateien
Was ist BTRFS-Fragmentierung?
Die meisten der besten BTRFS-Funktionen beruhen auf der Copy-on-Write-Technologie. Wenn eine Anwendung einen Teil einer Datei umschreiben will, z.B. das erste MegaByte, werden die Daten nicht an Ort und Stelle geschrieben, sondern in einer sogenannten Erweiterung. Dadurch ist BTRFS in der Lage, mehrere Versionen von teilweise umgeschriebenen Dateien aufzubewahren, wobei nur der den Änderungen zugewiesene Speicherplatz beansprucht wird und nicht mehrere vollständige Kopien einer Datei. Die alten Daten können zu einem bestimmten Zeitpunkt verworfen werden (z.B. wenn sie nicht mehr von Snapshots verwendet werden) und die Erweiterung dient der aktuellen Version der Datei.
BTRFS-Fragmentierung kann die Leistung Ihres Systems beeinträchtigen
Sie können sich vorstellen, dass das Lesen einer Datei mit 100k+ Erweiterungen und das Hinzufügen weiterer Erweiterungen eine Menge Buchführung und Speichersuchvorgänge von Ihrem System erfordert. Diese 10 GB große Datei ist intern in 100k+ Teile zerlegt, die gesammelt werden müssen, wenn Sie die gesamte Datei lesen wollen. Dies erhöht eindeutig die Komplexität - und verringert die Leistung.
BTRFS-Fragmentierung kann große Mengen an Speicherplatz blockieren
Ja, BTRFS muss die Speicherorte dieser 100k Erweiterungen irgendwo speichern, was leicht einige zusätzliche GB an belegtem Speicherplatz zu Ihrem System hinzufügen kann. Das Schlimme daran ist, dass BTRFS Ihnen das nicht mitteilt.
Wenn Sie sehen, dass Ihr btrfs-Dateisystem 80GB in df und btrfs fi show verwendet, während du -hsx nur 54GB anzeigt, gibt es nur zwei Gründe, die mir bekannt sind: entweder Sie haben Snapshots, die alte Erweiterungen behalten - oder Sie haben eine massive Fragmentierung.
BTRFS-Dateisystem defragmentieren
Es ist möglich, das BTRFS-Dateisystem auf dem gesamten Dateisystem zu defragmentieren, aber das führt dazu, dass alle Snapshots die Daten duplizieren. Es verursacht auch eine Menge IO, so dass dies nichts ist, was Sie auf Ihrem Produktionsserver ohne Grund tun wollen. Es macht wirklich keinen Sinn, statische Dateien zu defragmentieren, die fast nie geändert werden.
Finden Sie die am meisten fragmentierten Dateien auf Ihrem System
Es gibt ein Linux-Tool namens filefrag, das anzeigt, aus wie vielen Fragmenten eine Datei besteht. Also dachte ich ... "warum nicht versuchen, die am meisten fragmentierten Dateien zu finden und nur diese zu reparieren?" Hier ist es:
find / -xdev -type f| xargs filefrag 2>/dev/null | sed 's/^\(.*\): \([0-9]\+\) extent.*/\2 \1/' | awk -F ' ' '$1 > 500' | sort -n -r
Sie sollten diese Liste überprüfen. Wenn es etwas mit mehr als 10k Erstreckungen gibt, ist es ein Kandidat, um als nodatacow gekennzeichnet zu werden. In meinem Fall habe ich festgestellt, dass die Fail2ban-Sqlite-Datenbank 170k Erweiterungen verwendet, was sehr viel ist! Wenn Sie Datenbankdateien mit einer hohen Fragmentierung haben, während Sie nodatacow verwenden, ist es besser, eine "optimize table" auf ihnen laufen zu lassen, da dies auch die datenbankbezogene Fragmentierung von häufig neu geschriebenen Tabellen bereinigt. Wenn Sie Snapshots verwenden, stellen Sie sicher, dass Sie etwas freien Speicherplatz haben, da die Defragmentierung eine Kopie der Dateien an Ort und Stelle erstellt, während Snapshots die Freigabe der alten Version blockieren.
Wenn alles in Ordnung ist, können Sie fortfahren und alle Dateien in dieser Liste defragmentieren
find / -xdev -type f| xargs filefrag 2>/dev/null | sed 's/^\(.*\): \([0-9]\+\) extent.*/\2 \1/' |
awk -F ' ' '$1 > 500' | cut -d ' ' -f2 2>/dev/null | xargs -r btrfs fi defrag -f -v
Dies gibt alle Dateinamen aus, die verarbeitet wurden.
Eine kurze Erklärung des Befehls
find ermittelt alle Dateien auf dem angegebenen Pfad (/), ohne in andere eingehängte Dateisysteme zu gehen (-xdev). Dann bestimmt filefrag die Fragmentierung, der Befehl sed formatiert die Ausgabe so um, dass die Anzahl der Erweiterungen an erster Stelle steht, gefolgt vom Dateinamen. Dann analysiert awk diese Liste und filtert nur Dateien, die mehr als 500 Erweiterungen haben. Danach wird die Ausgabe so "geschnitten", dass sie nur die Dateinamen enthält, und an btrfs defrag zur Defragmentierung übergeben. Die Option -v des Defrag-Befehls gibt alle verarbeiteten Dateien aus. Werfen Sie auch einen Blick auf die langfristige IO-Nutzung vor und nach der Defragmentierung, um zu sehen, wie groß der Unterschied in der realen Welt ist.