MySQL-Backups mittels LVM Snapshots

Wie versprochen folgt nun ein Einblick in die Welt der MySQL Backups. Wer keine Lust auf technisches Blabla hat, der kann sich diesen Eintrag hier schenken, denn davon gibts hier einiges 😉

Das Problem

Im Gegensatz zu „normalen“ Backups gestalten sich Datenkbank-Backups etwas schwieriger, da man dem Server die Daten nicht einfach unter dem Arsch weg sichern kann, während dieser munter darin herum schreibt.

Ein erster Lösungsversuch

Am häufigsten wird für die Sicherung wohl der mysqldump benutzt (allein schon deswegen, weil das auch problemlos im PhpMyAdmin funktioniert). Das Tool, das standardmäßig mit MySQL mitgeliefert wird, sichert die Daten, indem es sie in SQL-Befehle (INSERTs) verpackt. Das Backup besteht aus einer (großen!) Textdatei, welche man zum Wiedereinspielen einfach ausführt.
Das hat zwei Vorteile: Man ist nicht von einer Bestimmten MySQL-Version abhängig (solange sich der SQL-Syntax nicht ändert, kann man auch seine Backups wieder einspielen) und man kann selbst (teilweise) beschädigte Backups retten, solange sie sich noch mit dem Texteditor öffnen lassen.
Leider läßt die Performance stark zu wünschen übrig, was kein Problem wäre, wenn nicht während der gesamten Zeit die Datenbank für Schreiboperationen gesperrt wäre. (Read-Lock), was unsere Seite faktisch lahm legt.
Das mußte also irgendwie besser gehn.

Backups 2.0

Wie oben schon geschrieben, kann man die Datenbanken nicht einfach wegkopieren, da der Server ständig in die Dateien schreibt. Hindert man den Server aber lang genug am Schreiben, kann man die Dateien doch einfach kopieren und somit die volle Festplattengeschwindigkeit fürs Backup nutzen.
Auch hierfür bietet MySQL bereits von Haus aus ein passendes Tool: mysqlhotcopy
Die Funktion ist wie bereits beschrieben: Das Script sperrt die Datenbank für Schreibzugriffe, schreibt alle Änderungen die noch im Arbeitsspeicher stehn auf die Platte (Flush) und kopiert dann einfach die Dateien (unter Debian standardmäßig in /var/lib/mysql/ zu finden) an das gewünschte Ziel. Anschließend wird die Datenbank wieder freigegeben.
Leider dauert selbst das noch zu lange, wenn sich erstmal ein paar GB an Daten angesammelt haben.
Aber wie kann man Daten schneller sichern, als durch Kopieren?

Des Rätsels Lösung

Linux bietet Unterstützung für das sog. „Logical Volume Management“ (kurz LVM) an. LVM nistet sich zwischen Festplatten und Dateisystem ein und bietet eine Abstraktionsschicht an, so dass man beispielsweise eine Partition über mehrere physikalische Platten verteilen kann (RAID). Das ist aber zum Glück noch nicht alles: LVM bietet die Möglichkeit Dateien zu kopieren, ohne sie wirklich zu kopieren.
Klingt komisch? – Ist aber so (ähnlich): Mit sogenannten Snapshots kann man ein Abbild des kompletten Dateisystems zum aktuellen Zeitpunkt erstellen. Ändert man danach eine Datei, so werden diese Änderungen an eine andere Stelle der Festplatte geschrieben, so dass das Original erhalten bleibt, die Änderungen aber trotzdem auf Platte stehn.
Auf diese Weise kann man in Sekundenbruchteilen, unabhänging von der Größe des Dateisystems, dessen aktuellen Zustand einfrieren.
Ein Backup läuft dann wie folgt:

  • Read-Lock setzen und Daten flushen
  • Snapshot anlegen
  • Read-Lock aufheben
  • Daten auf den Backupserver kopieren, während das System unbehelligt weiter läuft
  • (Snapshot löschen)

Eine gutes Howto dafür gibt es hier
Für automatisierte Backups (inkl. Read-Lock und Flush) habe ich ein kurzes PHP-Script gebastelt:

system(‚umount -f /mnt/backup‘);
system(‚lvremove -f /dev/vg_var/lv_backup‘);
$link = mysql_connect(‚localhost‘, ‚root‘, ‚asdf‘) or die (‚Could not connect: ‚.mysql_error());
mysql_select_db(‚db‘, $link) or die (‚Could not select database‘);
mysql_query(‚FLUSH TABLES WITH READ LOCK‘, $link);
system(‚lvcreate -L30G -s -nlv_backup /dev/vg_var/lv_var‘);
mysql_query(‚UNLOCK TABLES‘, $link);
system(‚mount -o nouuid,ro /dev/vg_var/lv_backup /mnt/backup‘);

Dank LVM laufen unsere Backups jetzt also ohne spürbare Systemaussetzer.

Über Fragen, Anregungen und Kommentare würde ich mich freuen.

5 Responses to “MySQL-Backups mittels LVM Snapshots”

  1. Denis sagt:

    Das klingt nach einer coolen, durchaus sinnvollen Lösung. 🙂
    Da dies genau mein momentanes Problem trifft, werd ich das dann wohl dies Wochenende auch mal ausprobieren 🙂

  2. Nitek sagt:

    Hats funktioniert?

  3. Denis sagt:

    Ich bin noch nicht über die Testszenarien hinaus gekommen. :p
    Aber da ich eine ähnliche Variante auch im MySQL High Performance-Buch gefunden hab, bekommt die Variante definitiv ihre Chance. 🙂
    (aber gut getestet muss es trotzdem werden. 😀 )

  4. Marc Richter sagt:

    Ein weiterer Nachteil von mysqlhotcopy, der unter Punkt „Backups 2.0“ meiner Meinung nach noch erwähnenswert ist, ist das sich nur myisam Tabellen mit diesem Tool zuverlässig backupen lassen. InnoDB und Konsorten bleiben auf der Strecke.

  5. Nitek sagt:

    Richtig, allerdings lassen sich InnoDBs ja einfach so wegkopieren (solange man die Transaction-Logs mit kopiert). Da ist mysqlhotcopy also ohnehin unnötig.

Leave a Reply