Backup der nächsten Generation mit BTRFS-Snapshots für Root-Fs und Datenbanken

Insider Blog

Autor

Bernd Helm

Steckbrief

Veröffentlicht:

September 6, 2017

Kategorien:

Das bewegt uns

Tags:

SSD

Wozu es gut ist

In diesem Artikel geht es um die Verwendung von BTRFS-Snapshots als Backup-Lösung, die für Datenbanken und vollständige Backups der Root-Partition verwendet werden können. Dies ist keine detaillierte Schritt-für-Schritt-Anleitung und erfordert einige Linux-Kenntnisse. Mit diesem Beitrag möchte ich meine Erfahrungen teilen und Ihnen etwas Ärger ersparen. Wir verwenden es seit Jahren in der Produktion.

Btrfs-Snapshots speichern eine "eingefrorene" Version des gesamten Dateisystems. Dies wird durch die Copy-On-Write (COW) Technik von BTRFS erreicht. Das bedeutet, dass Änderungen an Snapshot-Dateien nicht direkt in die Datei geschrieben werden, wie es bei klassischen Dateisystemen wie ext4 der Fall ist, sondern dass alle Änderungen an einer anderen Stelle geschrieben werden, so dass sowohl die aktuelle als auch die Snapshot-Version der Datei vorhanden ist. Diese Copy-On-Write (COW)-Technik bringt viele nette Funktionen in BTRFS, hat aber auch einige Nachteile, die Sie kennen sollten, bevor Sie BTRFS in der Produktion einsetzen. Siehe "COW auf Datenbankverzeichnissen immer deaktivieren" unten.

BTRFS verfügt über eine leistungsstarke Snapshot-Funktion, die es ermöglicht, Snapshots inkrementell auf entfernte Systeme zu übertragen. Es ist ganz einfach: Erstellen Sie einen Snapshot, übertragen Sie ihn auf ein entferntes System, erstellen Sie einen zweiten Snapshot und übertragen Sie nur die geänderten Blöcke aus dem vorherigen Snapshot. Solaris/FreeBSD-Benutzer machen das schon seit fast einem Jahrzehnt mit ZFS. Eine ZFS-Portierung ist auch für Linux verfügbar, so dass Sie es auch anstelle von BTRFS verwenden können, wenn Sie es aus irgendeinem Grund bevorzugen.

Anwendungsfälle von BTRFS-Snapshots

  • Sicherung von Root-Partitionen eines oder mehrerer Linux-Server auf einen zentralen Backup-Server
    • Es ist möglich, den Backup-Server direkt in einen der Snapshots zu booten, so dass ein manuelles Failover möglich ist
    • Die Snapshots können auch in virtuelle Maschinen übertragen werden. Dies ist sehr praktisch, wenn Sie möchten, dass Ihre "dev vm" mit dem Live-System auf dem neuesten Stand ist und sie regelmäßig mit inkrementellen Snapshots aktualisiert wird.
  • Sichern Sie MySQL-, Postgres- oder andere Datenpartitionen separat in einem anderen Zyklus als andere Einhängepunkte
  • Sie können BTRFS-Snapshots auf den Root-Partitionen verwenden, um nach einem fehlgeschlagenen System-Upgrade zu einem funktionierenden Rootfs zurückzukehren
  • Wenn Sie Entwickler sind, können Sie BTRFS-Snapshots lokal mit Ihrer Datenbank verwenden, um Ihre datenverändernde Anwendung immer wieder mit demselben Ausgangsdatensatz zu testen.
    • Sie können auch Ihre Dev-Datenbank-Snapshots mit Ihren Mitarbeitern teilen und ihnen inkrementelle Updates zur Verfügung stellen.

Sicherung einer Datenbank, Vor- und Nachteile der verschiedenen Methoden

Wenn Sie über Backups von MySQL/MariaDB (und einigen anderen Datenbanken) nachdenken, haben Sie einige Möglichkeiten, die Sie in Betracht ziehen können:

  1. Mysqldump verwenden, um ein logisches Backup zu erstellen (auch auf Basis der einzelnen Tabellen)
    1. Es ist langsam und belastet den Server spürbar
    2. Es ist schwierig, einen konsistenten Zustand zu erzeugen (erfordert Sperren oder einen Desync-Replikationsslave)
    3. Nicht inkrementell, selbst wenn nur geänderte Tabellen gesichert werden; wenn diese Tabellen groß sind, ist dies ein Problem.
    4. Wiederherstellung: Importieren Sie den Dump irgendwo, kann bei großen Datenmengen ewig dauern.
  2. Mysql-Binärprotokolle für inkrementelles Backup verwenden
    1. ermöglicht Point-in-Time-Recovery (Wiederherstellung zu einem beliebigen Zeitpunkt in der Vergangenheit)
    2. das Abspielen von Binär-Logs kann bei schreibintensiven Setups sehr lange dauern
    3. aus diesem Grund müssen Sie regelmäßig Vollsicherungen durchführen
  3. verwendet die inkrementelle Methode von innobackupex
    1. obwohl es fortschrittlicher ist, scheint es die gleichen Eigenschaften zu haben wie die Binär-Logs von mysql.
    2. Sie ist ebenfalls ressourcenintensiv und erfordert eine vollständige Datenbanksperre am Ende der Datenübertragung.
  4. Verwendung von Dateisystem-Snapshots
    1. keine Point-in-Time-Wiederherstellung
    2. endlos inkrementell, erst eine Vollsicherung und dann nur noch inkrementelle Sicherungen.
    3. schneller und ressourcenschonender Sicherungsprozess
    4. Wiederherstellung: Sie können eine Instanz Ihrer Datenbank von jedem Snapshot direkt auf dem Backup-System starten oder das komplette Mysql-Verzeichnis zurück auf den Quellserver verschieben, falls nötig.
    5. Der einzige Nachteil ist, dass Sie sich auf den datenbankeigenen Wiederherstellungsmechanismus bei Stromausfall verlassen müssen.

Während wir in der Vergangenheit mysqldump-Backups gemacht haben, verwenden wir jetzt die Dateisystem-Snapshot-Methode. Diese Methode hat sich als sehr zuverlässig, schnell und ressourcensparend erwiesen und ermöglicht außerdem eine einfache Wiederherstellung der gesicherten Daten. Es kommt sehr häufig vor, dass unsere Entwickler darum bitten, eine bestimmte Datenversion auf dem Backup-Server zu starten. Dies ist innerhalb von 10 Minuten erledigt und spart ihnen viel Zeit.

Ein Dateisystem-Snapshot ist ein konsistenter Zustand eines Dateisystems, der nicht mehr verändert wird. Aus Sicht der Datenintegrität stellt ein Snapshot einen unsauberen Zustand dar, wie man ihn nach einem Stromausfall, einem kill -9 oder einem "Out of Memory"-Fehler hat. Da MySQL/MariaDB und andere Datenbank-Engines so konzipiert sind, dass sie Stromausfälle überstehen, können Sie immer auch von einem Snapshot wiederhergestellt werden.

Stabilität von BTRFS und Produktionsreife

Über die Stabilität und Zuverlässigkeit von BTRFS ist in der Vergangenheit viel diskutiert worden. Obwohl es immer noch einige Bugs und Probleme haben kann, ist es unwahrscheinlich, dass diese zu Datenverlusten führen. BTRFS wird mit jeder neuen Linux-Kernel-Version verbessert, wir verwenden es seit Linux 3.17 in der Produktion und sogar noch länger auf unseren Workstations.

BTRFS-Snapshots für Backups verwenden

  • Wie bereits erwähnt, wird BTRFS mit jeder Linux-Kernel-Version verbessert, daher wird empfohlen, eine aktuelle Kernel-Version wie 4.9 LTS oder eine neuere zu verwenden.
  • Offensichtlich: da wir BTRFS-Snapshotting verwenden wollen, müssen wir die Daten, die wir sichern wollen, auf ein BTRFS-Volume legen.
  • Sie müssen BTRFS-Dateisysteme sowohl auf dem Quell- (Produktions-) als auch auf dem Zielserver (Backup) laufen haben.
  • Wenn Sie noch kein btrfs haben, können Sie die Größe Ihres aktuellen Dateisystems ändern, um Platz auf der Festplatte zu schaffen, und dort ein btrfs erstellen. Wenn Sie nur testen wollen, können Sie eine Image-Datei erstellen und diese mit losetup einbinden.
  • Wenn Sie bereits btrfs als rootfs verwenden, können Sie btrfs subvolume create verwenden, um ein neues Subvolume zu erstellen, z.B. für MySQL. Weil Sie vielleicht das MySQL-Datenverzeichnis häufiger sichern wollen als den Rest des Systems. Btrfs-Snapshots funktionieren auf der Basis von einzelnen Volumes. Wenn Sie also Dateien unabhängig voneinander sichern (oder von der Sicherung ausschließen) wollen, müssen Sie sie in ein Subvolume legen. Sie können mehrere Subvolumes von einem Rechner aus sichern, Sie müssen nur für jedes einen eigenen Sicherungsauftrag erstellen.
    • Ich erstelle ein Subvolume, um schnell wachsende Log-Verzeichnisse und temporäre Ordner mit Cache-Dateien, die nicht gesichert werden müssen, auszuschließen.
  • können Sie die BTRFS-Komprimierungsoptionen (wie compress=lzo) auf der Quelle, dem Ziel oder beiden verwenden.
  • Weitere Informationen über inkrementelle Backups mit BTRFS finden Sie im offiziellen Kernel-Wiki, https://btrfs.wiki.kernel.org/index.php/Incremental_Backup

Deaktivieren Sie immer COW auf Datenbankverzeichnissen!

Dies ist die wichtigste Lektion, die ich in Jahren der BTRFS-Nutzung gelernt habe: Deaktivieren Sie immer Copy-On-Write auf Datenbankdatenverzeichnissen. BTRFS hat eine COW-Funktion, die standardmäßig aktiviert ist, auch wenn kein Snapshot oder Hardlink vorhanden ist. Soweit ich weiß, sollte dies im Falle eines Stromausfalls eine Datenbeschädigung bei teilweise überschriebenen Dateien verhindern. Da dieses "Feature" aber btrfs-spezifisch ist und in den meisten anderen Dateisystemen nicht vorhanden ist, kann es als optional betrachtet werden. Für rootfs und die meisten Teile des Dateisystems schadet dies nicht, da die Dateien nur selten verändert werden. Alle DBMS wie Mysql oder Postgres erwarten keine COW-Funktion und führen COW und transaktionale Schreibvorgänge selbst durch.

Es macht keinen Sinn, COW auf FS-Ebene für ein Datenbankverzeichnis zu haben. Ganz im Gegenteil: BTRFS-COW auf einem Datenbankverzeichnis aktiviert zu haben, führt zu einer massiven Fragmentierung des Dateisystems, verlangsamt es und kann innerhalb einiger Monate zu BTRFS-Abstürzen führen. Wenn Sie Ihre Datenbank bereits auf BTRFS laufen lassen, ohne COW explizit zu deaktivieren, sollten Sie dies so schnell wie möglich tun, bevor es noch schlimmer wird.

  • Wenn Sie ein neues BTRFS für Ihre Datenbank erstellen, mounten Sie es immer mit der Option nodatacow, BEVOR Sie die erste Datei schreiben.
  • COW wird zum Zeitpunkt der Dateierstellung aktiviert/deaktiviert. Wenn Sie Dateien mit COW erstellt haben und das Dateisystem später mit nodatacow einhängen, sind die alten Dateien immer noch COW-aktiviert. Sie müssen sie kopieren, um COW tatsächlich zu deaktivieren.
  • Es gibt ein no-COW-Flag, das Sie für Verzeichnisse mit chattr +C /pfad setzen können. Das Setzen von +C für ein Verzeichnis bewirkt, dass alle untergeordneten Verzeichnisse/Dateien COW-frei sind.
  • Wenn Sie bereits eine Datenbank mit COW haben, können Sie es auf diese Weise deaktivieren (z.B. für MySQL):
/etc/init.d/mysql stop # make sure your database is stopped!
mv /var/lib/mysql /var/lib/mysql_old
mkdir /var/lib/mysql
chattr +C /var/lib/mysql
cp -a /var/lib/mysql_old/* /var/lib/mysql
rm -rf /var/lib/mysql_old
chown -R mysql:mysql /var/lib/mysql
/etc/init.d/mysql start #start db again
  • Beachten Sie, dass der Kopiervorgang sehr (in manchen Fällen sehr) lange dauern kann, wenn Ihre Datenbank groß und bereits stark fragmentiert ist. Sie können testen, wie lange der Kopiervorgang dauert, bevor Sie die Datenbank auf einem Produktionssystem herunterfahren.
    • Wenn Sie den Kopiervorgang beschleunigen wollen, können Sie btrfs filesystem defrag -v -r -f /var/lib/mysql/ verwenden, während Ihre Datenbank läuft.

BTRFS-SxBackup als Sicherungsmanager

BTRFS-SxBackup ist eine einfache Python-CLI-Applikation, die es sehr einfach macht, BTRFS-Snapshots zu erstellen, zu übertragen und zu verwalten. Ich empfehle sie sehr, da sie einfach zu benutzen ist. Nach dem Einrichten können Sie es mit einem Cronjob ausführen.

  • Installieren Sie BTRFS-SxBackup von https://github.com/masc3d/btrfs-sxbackup auf dem Backup-Server. Mit btrfs-sxbackup auf dem Zielsystem wird das Backup "gezogen" und zentral vom Backup-Server verwaltet (der Client muss nur ssh laufen haben). Sie können auch btrfs-sxbackup auf dem Quellsystem einrichten und ein "Push"-Backup durchführen, wenn Sie möchten.
    • Auf dem Ziel-(Backup-)Server ** empfehle ich dringend, LVM zu verwenden und ein BTRFS-Volume für jeden Backup-Auftrag zu erstellen.** Machen Sie die Volumes nicht zu groß, Sie können sie leicht erweitern, wenn Sie mehr Platz benötigen. In der Vergangenheit hatten wir das Problem, dass die Speicherung und Verwaltung vieler Snapshots in einem btrfs-Zielvolume zu Fehlern führen kann, die ein Dateisystem unbeschreibbar machen. Die Erstellung eines btrfs-Volumes pro Backup-Auftrag macht BTRFS schneller und sicherer - und im Falle von BTRFS-Problemen ist nur ein Backup betroffen. (und Sie haben noch Platz, um ein neues BTRFS zu erstellen und die Backups dort fortzusetzen). Nachdem wir es auf diese Weise auf dem Backup-Server gemacht haben, sind alle Probleme, die wir vorher mit einem einzigen btrfs-backup-fs hatten, verschwunden.
    • Erstellen Sie einen ssh-Schlüssel für root auf dem Backup-Server und fügen Sie ihn der authorized_keys-Datei auf der Quelle hinzu. Auch für den root-Benutzer. btrfs-sxbackup erfordert das Erstellen, Übertragen und Löschen von Snapshots und nur root kann das tun.
    • Sie müssen die Befehle btrfs-sxbackup init und run verwenden, um den Sicherungsprozess einzurichten und zu starten. Weitere Informationen finden Sie in der BTRFS-SxBackup git readme. Sie können auch die Übertragungskomprimierung einschalten.
    • BTRFS-SxBackup hat eine Aufbewahrungsfunktion; d.h. wenn Sie jede Stunde eine Datenbanksicherung machen, können Sie die letzten beiden auf der Quelle aufbewahren und Regeln konfigurieren wie "nach zwei Wochen nur noch 4 Sicherungen pro Tag".
  • Wiederherstellung: Wenn Sie btrfs für (Root-)Dateisystem-Backups verwenden, können Sie die einfachen Dateien direkt aus dem Dateisystem des Backup-Servers lesen. Wenn Sie eine vollständige Wiederherstellung benötigen, können Sie die Befehle btrfs send und btrfs receive verwenden, um Ihr Backup wiederherzustellen.
    • Sie können Ihren Backup-Server auch in einen Snapshot booten, indem Sie die Kernel-Option subvol= verwenden. Siehe auch hier

Tipps zur Wiederherstellung eines MySql/MariaDB-Datenbank-Snapshots

Wenn Sie BTRFS für MySQL-Backups verwenden, möchten Sie wahrscheinlich die Daten Ihrer MySQL-Tabellen untersuchen oder eine einzelne Tabelle oder Datenbank wiederherstellen.

  • Installieren Sie in diesem Fall die gleiche Hauptversion von MySQL/MariaDB wie auf dem Quellsystem.
  • Die Snapshots auf dem Backup-Server sind schreibgeschützt, mysql kann auf einem schreibgeschützten Dateisystem nicht starten. Um dies zu beheben, erstellen Sie einen neuen Snapshot des schreibgeschützten Snapshots, der standardmäßig beschreibbar sein wird: btrfs sub snap sx-
  • Falls das Quellsystem eine andere Benutzerkennung für mysql hat als das Backup-System, müssen Sie einen chown -R mysql:mysql auf dem beschreibbaren Volume durchführen.
  • Konfigurieren Sie das Datenverzeichnis my.cnf so, dass es auf das Restore-Volume zeigt und starten Sie mysql. Beobachten Sie die Logdatei .err auf dem Restore-Volume für den Startvorgang. Sie brauchen die Live-MySQL-Konfiguration nicht zu kopieren, stellen Sie nur sicher, dass die wichtigsten Optionen korrekt eingestellt sind.
  • Nachdem das Starten/Wiederherstellen erfolgreich abgeschlossen wurde, können Sie sich mit Ihren Produktionsbenutzern/Passwörtern auf der Sicherungsinstanz anmelden, die Daten prüfen und mysqldump verwenden, um die Tabellen zurück auf das Produktionssystem zu übertragen. Sie können auch btrfs send/receive verwenden, um den kompletten Snapshot zurück zur Quelle zu übertragen, falls eine Notfallwiederherstellung erforderlich ist.
  • Wenn Sie eine Backup-Instanz laufen haben, ist dies ein voll funktionsfähiger und beschreibbarer Snapshot der Produktionsdaten, der auch für Tests vor dem Einsatz verwendet werden kann.

Bekannte Probleme und Lösungen

Hilfe! Ich bekomme die Meldung "kein Speicherplatz auf dem Gerät verfügbar", aber ich habe noch eine Menge Speicher übrig!

Dies ist ein häufiges Problem mit BTRFS. Ich habe einige Zeit gebraucht, um eine Idee zu bekommen, was da schief läuft. Meine Erklärung dafür ist, dass BTRFS Daten- und Metadatenblöcke auf dem physischen Gerät zugewiesen hat. Manchmal kommt es vor, dass der gesamte freie Platz durch fast leere Datenblöcke belegt ist. Wenn neue Daten geschrieben werden, kommt BTRFS an den Punkt, an dem die neuen Metadaten nicht mehr in die vorhandenen Blöcke passen und btrfs muss einen neuen Metadatenblock zuweisen. Da der gesamte freie Speicherplatz bereits von teilweise oder vollständig leeren Datenblöcken beansprucht wird, ist kein Platz mehr vorhanden, um einen neuen Metadatenblock zuzuweisen. Dies führt zu der Meldung "no space left on device", nicht weil die Daten nicht passen, sondern weil BTRFS nicht in der Lage ist, Platz für die Metadaten zu schaffen. Die Lösung besteht darin, einen btrfs balance start /path -dusage=x auszuführen. Der balance-Befehl sucht nach Blöcken, die nur zu x% oder weniger belegt sind, verschiebt deren Daten in andere Blöcke und löscht sie anschließend, wodurch Platz für neue Blockzuweisungen frei wird. Man kann mit 5 oder 10% beginnen und bis zu dem von df angezeigten Prozentsatz (oder knapp darunter) gehen.

Ich habe in den BTRFS-Dokumenten gelesen, dass BTRFS sich bei Bedarf selbst ausgleicht. Ich kann dies nicht bestätigen, daher habe ich auf wichtigen Produktionssystemen einen täglichen Cronjob mit btrfs balance start -dusage=20 eingerichtet, um sicherzustellen, dass ich keine Probleme bekomme. Vielleicht ist das Problem behoben oder wird in den nächsten btrfs-Versionen behoben, aber ich möchte nicht darauf wetten.

Ich erhalte auch "no space left on device" wenn ich btrfs balance ausführe

BTRFS braucht etwas Speicherplatz, um Plattenplatz freizugeben, ja. Versuchen Sie zunächst -musage statt -dusage und sehen Sie, ob dies das Problem löst. Sie können auch versuchen, einige Dateien zu löschen, aber auch das kann zu der Fehlermeldung "no space left on device" führen.

Die endgültige Lösung für dieses Problem besteht darin, dem vollständigen Dateisystem vorübergehend ein neues Blockgerät hinzuzufügen, damit es ausgeglichen werden kann. Wenn Sie keine freie Partition zum Hinzufügen haben, können Sie auch mit dd eine Datei in ein anderes Dateisystem schreiben, z. B. in ein reines RAM-Dateisystem (tmpfs), dann mit losetup ein Blockdevice erstellen und es zu BTRFS hinzufügen. Eine Größe von 2-5GB funktioniert meistens. Beginnen Sie den Ausgleich mit -dusage=0 und erhöhen Sie langsam, bis einige Blöcke verschoben sind. Nach einigen Verlagerungen können Sie das hinzugefügte Gerät mit dem Befehl btrfs drive remove entfernen.

Achtung: Wenn Sie eine TMPFS-Datei zu Ihrem BTRFS-Dateisystem hinzufügen, klopfen Sie auf Holz, dass es keinen Stromausfall oder Kernel-Crash gibt, sonst beschädigen Sie Ihr Dateisystem. Die Verwendung eines TMPFS ist eine Notlösung. Fügen Sie besser einen USB-Speicher oder einen Netzwerkspeicher mit nfs oder sshfs hinzu, wenn möglich.

Vorheriger Artikel
Für Entwickler, Für Shopbetreiber - Wir arbeiten nicht mit beliebigen Frameworks, Bibliotheken, Plugins und Programmiersprachen. Wir lieben es professionell. Software, die bei Helm & Walter entsteht, soll leistungsfähig und schlank sein. Hier unsere Favoriten: PHP (rekursives Akronym für PHP: Hypertext Preprocessor) ist eine weit verbreitete und für den …
June 27, 2017
Bernd Helm
Nächster Artikel
Wenn man versucht, Speicherplatz zurückzugewinnen, scheint das Löschen von Daten der naheliegende erste Schritt zu sein. In Riak ist dies jedoch nicht unbedingt die beste Lösung, wenn die Festplatte fast voll ist...
September 26, 2017
Daniel Walter