Wie Markus in seinem letzten Blogpost schon beschrieben hat, hatte er die zweifelhafte Ehre ein Backup einer verhältnismäßig großen MySQL-Datenbank (MariaDB) zu machen. Das große Problem bei ihm war allerdings, dass das Kopieren auf Dateiebene eine Downtime der Datenbank voraussetzte und somit der laufende Betrieb eingestellt werden musste. Man legt sozusagen die Datenbank auf Eis und deshalb nennt man dieses Verfahren auch Cold Backup (Offline Backup). Dies war zumindest meine Schlussfolgerung zur Namensgebung…

Als wissensdurstiger Azubi bei NETWAYS wollte ich wissen ob es vielleicht eine Möglichkeit gibt, ein Backup einer MySQL-Datenbank während  des laufenden Betriebes zu machen. Bei meinen Recherchen bin ich letztlich auf ein heiß diskutiertes Thema gestoßen. Wie der Name schon sagt, auf das “heiße”, sogenannte Hot Backup (Online Backup). Bei diesem Backupverfahren ist es möglich während des laufenden Betriebes einer MySQL-Datenbank ein Backup zu erstellen und somit eine Downtime der Datenbank zu vermeiden. Das Online Backup kann somit mehrmals am Tag durchgeführt werden, des Weiteren ist es deutlich schneller als das Offline Backup. Allerdings birgt ein Hot Backup auch ein gewisses Risiko, da im Gegensatz zum Cold Backup, weiter Daten in die Datenbank geschrieben werden und diese somit nicht im Backup enthalten wären. Das wäre aber im Ernstfall (Ausfall der Datenbank) zu verschmerzen, da somit beispielsweise womöglich nur Daten der letzten paar Stunden und nicht von einem ganzen Arbeitstag verloren wären.

Im Folgenden zeige ich anhand eines kleinen Beispiels, wie so ein Hot Backup vonstatten geht. Das Tool meiner Wahl ist Xtrabackup von Percona. Xtrabackup kann ein Hot Backup erstellen indem es sich die sog. crash-recovery Funktion von InnoDB-Datenbanken zu Nutze macht. Die Installation von Xtrabackup ist in der Dokumentation hervorragend beschrieben.

Zunächst benötigt man einen Datenbankuser mit folgenden Rechten:
mysql> CREATE USER 'backupuser'@'localhost' IDENTIFIED BY 'SuperGeheim!';
mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backupuser'@'localhost';
mysql> GRANT SELECT ON performance_schema.log_status TO 'backupuser'@'localhost';

Der nächste Schritt ist ein Backup anzustoßen:
$ xtrabackup --backup --user=backupuser --password=SuperGeheim! --target-dir=/var/test_backup
“–target-dir”: In diesem frei zu wählenden Ordner werden die Backups gespeichert.

Man kann bei der Ausgabe sehr gut erkennen, dass Xtrabackup sich die sog. LSN (Log Sequence Number) “merkt” und ab diesem Zeitpunkt die Tabellen der Datenbank sperrt sowie alle weiteren Schreiboperationen “puffert”. Nach dem Kopieren der Daten werden die Tabellen wieder frei gegeben und der Betrieb ab der “gemerkten” LSN wieder aufgenommen:
190829 10:27:43 >> log scanned up to (146090017)
xtrabackup: Generating a list of tablespaces
190829 10:27:43 [01] Copying ./ibdata1 to /var/test_backup/ibdata1
190829 10:27:44 [01] ...done
190829 10:27:44 >> log scanned up to (146090017)
190829 10:27:44 Executing FLUSH NO_WRITE_TO_BINLOG TABLES...
190829 10:27:44 Executing FLUSH TABLES WITH READ LOCK...
190829 10:27:44 Starting to backup non-InnoDB tables and files
[...]
[...]
190829 10:27:46 Finished backing up non-InnoDB tables and files
190829 10:27:46 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...
xtrabackup: The latest check point (for incremental): '146090233'
xtrabackup: Stopping log copying thread.
.190829 10:27:46 >> log scanned up to (146090233)
190829 10:27:46 Executing UNLOCK TABLES
190829 10:27:46 All tables unlocked
190829 10:27:46 Backup created in directory '/var/test_backup'
190829 10:27:46 [00] Writing /var/test_backup/backup-my.cnf
190829 10:27:46 [00] ...done
190829 10:27:46 [00] Writing /var/test_backup/xtrabackup_info
190829 10:27:46 [00] ...done
xtrabackup: Transaction log of lsn (146086198) to (146090233) was copied.
190829 10:27:46 completed OK

Wenn das Backup erfolgreich war und man dieses wieder einspielen will, muss man dieses zuvor “vorbereiten”. Da die kopierten Daten womöglich nicht mit den aktuellen Daten übereinstimmen:
$ xtrabackup --prepare --target-dir=/var/test_backup

Hat man ein InnoDB: Shutdown completed; log sequence number 146093758
190829 10:45:05 completed OK!
erhalten, lässt sich das Backup wiederherstellen

ACHTUNG: Es müssen beim Wiederherstellen alle Daten aus /var/lib/mysql/ gelöscht werden. Hierbei sollte man sehr aufpassen, ansonsten kann es zum kompletten Datenverlust führen!!!

Um das “vorbereitete” Backup einzuspielen, muss der MySQL (MariaDB) Dienst gestoppt sein (was bei einem Ausfall sowieso der Fall sein dürfte). Der nächste Schritt wäre den Benutzer der Daten anzupassen und den Dienst erneut zu starten:
$ systemctl stop mariadb.service
$ rm -rf /var/lib/mysql/*
$ xtrabackup --move-back --target-dir=/var/test_backup
$ chown -R mysql:mysql /var/lib/mysql/
$ systemctl start mariadb.service

Als Fazit kann man sagen, dass sich Hot Backups sehr lohnen, aber auch ein gewisses Risiko beherbergen können. Cold Backups sind dazu im Gegensatz sehr “starr” und können nur während einer Downtime durchgeführt werden. Sie bieten jedoch die höhere Chance auf Datenkonsistenz und sind deutlich einfacher zu handhaben. Empfehlenswert ist es auf jeden Fall sich eine geeignete Datensicherungsstrategie aus beiden Varianten zu überlegen, bei der man zum Beispiel am Ende des Tages ein Cold Backup und während der Geschäftszeiten mehrere Hot Backups macht.

Philipp Dorschner
Philipp Dorschner
Junior Consultant

Philipp hat im September 2017 seine Ausbildung zum Fachinformatiker gestartet. Er hat sogar schon eine Ausbildung im Gepäck und zwar zum technischen Assistenten für Informatik. Danach hat hat er sein Abi nachgeholt und anschließend begonnen Wirtschaftswissenschaften zu studieren. Da sein Herz während des Studiums ständig nach technischen Inhalten geschrien hat, wechselte er zu Verfahrenstechnik. Aber auch dieses Studium konnte Ihn nicht erfüllen, weshalb er sich für die Ausbildung bei NETWAYS entschieden hat, "back to the...