Problem
Beim Backup von MySQL-Servern mit VMWare Data Protection, Veeam und mit Snapshots im Allgemeinen ist zu beachten:
- Ein Backup-Snapshot eines laufenden MySQL-Servers enthält nicht den Inhalt des RAMs.
- /var/lib/mysql im Snapshot stimmt nicht mehr mit dem RAM überein und ist möglicherweise korrumpiert.
- Schlussfolgerung: Dieser Snapshot ist als Backup unbrauchbar.
Das Problem ist nicht VMWare-spezifisch sondern tritt immer auf, wenn man MySQL im laufenden Betrieb per Disk-Kopie sichern will, ohne den Zustand des RAMs zu beachten.
Lösung 1: Keine Block- oder File-basierte Sicherung von Daten in MySQL
Aufgrund der obigen Problematik kann argumentiert werden, dass dateibasierte Sicherheitskopien eines MySQL-Servers grundsätzlich nicht dazu geeignet sind, die Daten in den DBs wiederherzustellen.
Folgerichtig kann ein Datei-Backup nur dazu dienen, die Serversoftware (das installierte MySQL mit allen aktuellen Updates und Anpassungen) wiederherzustellen.
Zur Datenwiederherstellung müssen Dumps der DBs erstellt und verwendet werden. Eine Replikation auf einen MySQL-Slave-Server kommt zusätzlich in Frage (man braucht dann ohnehin Dumps, um den Slave bei Abriß der Replikation wieder synchronisieren zu können).
Lösung 2: Lock/Flush/Snapshot/Unlock
Übersicht
1. Zuerst FLUSH TABLES WITH READ LOCK. Der DB-Server ist ab jetzt für Anfragen von außen „readonly“ und eingehende Verbindungen landen in der „Warteschleife“ (siehe auch Hinweise unten, der DB-Server ist damit jedenfalls für Änderungen von aussen gesperrt).
Im Anschluss muss gewartet werden, bis der Wert der globalen Status-Variable Innodb_buffer_pool_pages_dirty auf 0 gesunken ist. Umsetzungs-Vorschlag in Bourne Shell:
while sleep 1 ; do
value=$(mysql -bsse '
SHOW GLOBAL STATUS LIKE "Innodb_buffer_pool_pages_dirty"' |
cut -f 2)
if test "$value" = "0" ; then
break
else
echo "Innodb_buffer_pool_pages_dirty = $value"
fi
done
2. Dann den Snapshot erstellen. Ab diesem Schritt kann das Backup diesen „eingefrorenen“ Zustand des Dateisystems im Hintergrund auslesen, während das System weiterläuft.
3. Dann UNLOCK TABLES. Jetzt werden die seit Schritt 1 in der „Warteschleife“ gehaltenen Queries abgearbeitet.
Umsetzung in Virtualisierungs-Lösungen
- In Veeam Backup & Replication for VMWare kann man das mit „pree-freeze“ und „post-thaw“ Skripten basteln (siehe auch Links [1] und [2]).
- In VMWare Dataprotection (VDP) hingegen scheinen freeze/thaw-Skripten nicht für Linux-Guests unterstützt zu werden (bin mir nicht sicher ob meine Info aktuell ist, aber im VDP Manual habe ich nichts dazu gefunden).
- In Systemen, in denen man die Snapshots direkt auf FS-Ebene durchführt bzw. skriptet, hat man eine bessere Kontrolle über den Ablauf des Vorgangs.
Hinweise
- Das Read Lock zu akquirieren kann dauern. Wenn FLUSH TABLES WITH READ LOCK ausgeführt wird, während eine lange Query läuft, dauert das Akquirieren des Locks so lange, bis die Query beendet ist. Veeam & Co. können dabei in einen Timeout laufen, und der Snapshot schlägt fehl (und damit die Sicherung). Lösungen wie Percona innobackupex (siehe [3]) haben Optionen, die das Beenden von Queries erzwingen können, sobald ein Backup angefordert sind; das erzwungene Abbrechen schreibender Query gefährdet aber die Integrität der Daten, zum Beispiel weil Foreign Keys verloren gehen können.
- Noch komplizierter wird die Situation, wenn es noch andere Clients, Skripts o.ä. gibt, die ebenfalls Locks akquirieren können; insbesondere wenn eine MySQL-Session zuvor ein WRITE LOCK angefordert hat, wird das READ LOCK erst verfügbar, wenn die andere Session ihr WRITE LOCK freigegeben hat.
- Wenn MySQL so konfiguriert ist, dass das General- oder Slow-Query-Log in DB-Tabellen geschrieben werden soll, dann wird das Schreiben in diese Tabellen nicht durch FLUSH TABLES WITH READ LOCK unterbunden (siehe [4]).
Fazit
Es ist meine Auffassung, dass das Sichern der Daten in einem MySQL-Datenbankserver durch Snapshots der Dateien mit zuvielen Unwägbarkeiten, Timeouts und Spezialfällen verbunden ist, um zuverlässig zu sein.
Für das Sichern von Daten sollten andere Verfahren wie Datenbank-Dumps, Binlog und Replikation verwendet werden.
Links
- [1] Veeam Admin Manual, Abschnitt Pre-Freeze and Post-Thaw Scripts“.
URL: http://helpcenter.veeam.com/backup/80/vsphere/backup_job_vss_scripts_vm.html - [2] Blog-Eintrag mit Beispielen für „pre-freeze“, „post-thaw“ Skripten u.a.
URL: https://www.virtuallifestyle.nl/2013/03/back-up-mysql-on-linux-without-stopping-services-or-dumping-the-database/ - [3] Percona.com. „The innobackupex Script“.
URL: https://www.percona.com/doc/percona-xtrabackup/2.2/innobackupex/innobackupex_script.html - [4] MySQL 5.7 Manual. Abschnitt „FLUSH TABLES Syntax“.
URL: http://dev.mysql.com/doc/refman/5.7/en/flush.html#idm140389868095328