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