Bislang habe ich, um die Datenkonsistenz der Backups von Mailservern sicherzustellen, eigentlich immer offline gesichert. D.h. Postfix und Cyrus gestoppt, die Daten mit rsync weggesichert und die Mailserverdienste wieder gestartet. Ein sehr unbefriedigendes Mittel, auch wenn die Offline-Zeiten des MTA sehr absehbar sind und um 3 Uhr morgens nicht wirklich jemanden stören.
Aus diesem Grund machte ich mich vor der letzten Mailserver-Installation auf die Suche nach einer besseren Backup-Methode, einer die möglichst ohne Mailserver-Auszeit auskommen sollte.
Und da ersuchmaschinte ich ein Feature des Linux Logical Volume Manager (LVM), dass ich persönlich bis dato gar nicht kannte: Snapshots.
Für diejenigen, die noch nicht mit dem LVM gearbeitet haben:
Was sind Logical Volumes?
Theoretisch können mehrere physikalische Datenträger (oder Partitionen) zu einer logischen großen Einheit (der sog. Volumegroup, oder kurz VG) zusammengefasst werden, die sich, vereinfacht gesagt, nach außen hin als eine großer Datenträger präsentiert.
In der erstellten Volume-Group werden dann wieder Logische Volumes (sinnigerweise als LV abgekürzt) erstellt, die sich als formatierbare Partitionen darstellen.
Warum diese ganze Bastelei?
Nun, man stelle sich vor, in einem Server hängen zwei Platten mit je 50GB Plattenplatz, man benötigt aber für eine Partition 80GB. Im Normalfall müsste man nun einen 80GB-Datenträger zusätzlich in den Rechner hängen, damit man eine entsprechend große Partition anlegen kann. Mit dem LVM erstellt man stattdessen einfach für die beiden vorhandenen Platten je ein Physical Volume (PV) und hängt diese in eine Volume Group. So erhält man einen virtuellen Datenträger mit 100GB. Nun kann man darauf ein logisches Volume mit 80GB erstellen und erhält somit die gewünschte Partition, die sich jetzt einfach formatieren und anschließend mounten lässt.
Und was ist ein Snapshot?
Vereinfacht gesagt, funktioniert das so: Wird ein Snapshot für ein Logical Volume angelegt, friert der Zustand des Volumes quasi ein und wird als eigenes Device zur Verfügung gestellt.
Solange der Snapshot aktiv ist, laufen alle Dateioperationen auf das eigentliche LV in eine Art “Puffer”. Dieser Puffer wird nach dem Aushängen des Snapshots wieder in das LV integriert, die Anwendungen, die mit dem betroffenen Volume arbeiten, merken von dieser Aktion nichts und können ganz normal weiterlaufen.
Der Snapshot selbst ist konsistent, man sichert also Daten von einem Datenträger, dessen Inhalte sich in einem definierten Zustand befinden und sich während des Backup-Vorgangs nicht ändern.
Wer weitere Informationen zum LVM haben möchte, dem sei das LVM Howto von AJ Lewis als Lesematerial empfohlen.
Aber jetzt auf zur Praxis:
Auf dem gerade genannten Mailserver (bestückt mit Debian Etch) sollte für den Mountpoint /var ein LV mit 200GB eingerichtet. Als Datenträger stand mir /dev/sdb mit einer Kapazität von 400GB zur Verfügung.
Mit
# pvcreate /dev/sdb
# vgcreate vg_var /dev/sdb
# lvcreate -L200G -nlv_var /dev/vg_var
# mkfs.ext3 /dev/vg_var/lv_var
erstellte ich mir ein ext3-formatiertes Device unter /dev/vg_var/lv_var.
Aber da das Ganze während des Normalbetriebes des Servers stattfand, konnte ich das LV nicht einfach unter /var einhängen, denn da waren ja schon Daten drin.
Mein kleiner Workaround sah wie folgt aus:
Zunächst wurden alle Services gestoppt, die noch auf /var zugriffen. Neben den eigentlichen Mailserverdiensten waren das auch beispielsweise der syslog-Daemon und acpid. (Wer auf /var noch aktiv ist, lässt sich mit “lsof |grep \/var” ermitteln.)
Jetzt konnte ich die Daten verschieben und die neue Partition unter /var zur Verfügung stellen:
# mkdir /media/var_neu
# mount /dev/vg_var/lv_var /media/var_neu
# cd /var
# tar cv - . | (cd /media/var_neu; tar xv -)
# cd /
# umount /media/var_neu
# mv /var /var_backup
# mkdir /var
# mount /dev/vg_var/lv_var /var
Und für den nächsten Systemstart musste natürlich noch ein Eintrag in die /etc/fstab:
/dev/vg_var/lv_var /var ext3 defaults 0 0
Das war’s eigentlich auch schon, es fehlte nur noch der Neustart der soeben beendeten Dienste.
Wem es zu mühsam ist, alle vorhin beendeten Dienste wieder manuell zu starten, der kann den Server jetzt ja auch durchbooten, um zu sehen, ob die OP am lebenden Objekt erfolgreich verlaufen ist.
So, jetzt konnte endlich die erste Schnappschuss-Sicherung durchgeführt werden:
# mkdir /media/snapshot_backup
# lvcreate -L50G -s -nlv_backup /dev/vg_var/lv_var
# mount /dev/vg_var/lv_backup /media/snapshot_backup
# tar czvf /mein/archiv.tgz /media/snapshot/backup
# umount /dev/vg_var/lv_backup
# lvremove -f /dev/vg_var/lv_backup
Die Snapshot-Größe von 50G habe ich gewählt, damit während meiner Sicherei genug Platz für die Daten vorhanden ist, die gepuffert werden müssen. Der Platz sollte natürlich in der Volume Group auch noch zur Verfügung stehen.
Das war eigentlich auch schon die ganze Herrlichkeit.
Auch für die Sicherung von MySQL-, Postgres oder Wasauchimmerfür-Datenbanken wäre diese Vorgehensweise denkbar, doch da setze ich dann doch lieber auf die altbewährten Dumps, die ich auch online durchführen kann.
3. Februar 2008 um 10:25
Aber Vorsicht: die Dienste sollte man vor dem Snapshot trozdem kurz beenden, snapshot, dann wieder starten. Da man sonst evetuell Datensichert die von der Software des Dienstes her nciht konsistent sind. Gerade bei Datenbankserver ist das Problem. (mal abgesheen von pid files.. die noch am einfachten lösbar sind beim wiederherstellen)
3. Februar 2008 um 10:29
Achja und man sollte acuh das beachten:
“Snapshots and mirrors may not yet be mixed.”
Ich nutze LVM um einfacher ne 1:1 spigelung zu machen (mit md muss man entweder nen ganzes PV spiegeln (funtzt), oder auf online-resize verzichten.
19. September 2008 um 21:56
[...] gutes Howto dafür gibt es hier Für automatisierte Backups (inkl. Read-Lock und Flush) habe ich ein kurzes PHP-Script [...]