Backups mit der MySQL Clone Operation
Kürzlich haben wir das PostgreSQL Backup-Tool pg_basebackup getestet und dort grossen Gefallen an der remote-Backup Funktionalität gefunden, welche sowohl ein physisches lokales als auch ein physisches remote Backup erlaubt.
Dabei hat sich bei uns die Frage gestellt, ob ein physisches remote Backup auch mit der “neuen” MySQL Server Clone-Funktionalität möglich ist, welche mit MySQL 8.0.17 (Juli 2019) dazu gekommen ist.
Mit der MySQL Clone-Operation kann sowohl eine lokale als auch eine remote Kopie der Datenbank erstellt werden. Die ursprüngliche Idee für dieses Feature war wahrscheinlich, Knoten im InnoDB Cluster automatisiert zu erstellen (analog zum Percona XtraDB Cluster SST).
Die bei der Clone-Operation verwendete Terminologie:
- Donor (Geber, Quell-Datenbank der Daten)
- Recipient (Empfänger, Ziel der Daten(-Bank))
Die Clone-Operation wird vom Recipient aus gestartet. Die Daten können ins eigene, alternativ aber auch in ein anderes Verzeichnis geclont werden.
Vorbereitungen
Das Plugin muss sowohl auf dem Donor als auch auf dem Recipient installiert sein.
SQL> INSTALL PLUGIN clone SONAME 'mysql_clone.so';
Query OK, 0 rows affected (0.01 sec)
SQL> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME = 'clone'
;
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone | ACTIVE |
+-------------+---------------+
Wenn das Laden des Plugins beim Neustart erzwungen werden soll, muss es wie folgt in der MySQL Konfigurationsdatei (my.cnf) konfiguriert werden:
[mysqld]
plugin_load_add = mysql_clone.so
clone = FORCE_PLUS_PERMANENT
Lokales Backup mittels Clone
Diese Variante kann als Ersatz einer physischen Backup Lösung (xtrabackup oder MySQL Enterprise Backup (mysql_backup)) dienen.
Auf der Datenbank, welche in diesem Fall als Recipient agiert, wird folgender Befehl ausgeführt:
SQL> CLONE LOCAL DATA DIRECTORY = '/mnt/backup/mysql_clone';
Was bei der Clone-Operation noch fehlt sind:
- Die ganzen TLS Schlüssel (
*.pemFiles). - Die Datei
auto.cnfwelche dieserver_uuidenthält. - Die Datei
mysqld-auto.cnfwelche dynamisch geänderte, persistierte Server Konfigurationsvariablen enthält. - Die
mysql_upgrade_history. - Die MySQL Konfigurationsdatei (
my.cnf) sowie - die Binary Logs.
$ cp ${datadir}/*auto.cnf ${datadir}/mysql_upgrade_history ${datadir}/*.pem /mnt/backup/mysql_clone/
Das Wiederherstellen der Datenbank ist recht einfach:
$ systemctl stop mysql
$ rm -rf ${datadir}/*
$ cp -a /mnt/backup/mysql_clone/* ${datadir}/
$ chown -R mysql: ${datadir}/*
$ systemctl start mysql
Der Ordner #clone wird durch die Clone-Operation erstellt und kann ignoriert, darf aber nicht gelöscht werden.
$ ls -lad /mnt/backup/mysql_clone/*
...
drwxr-x--- 2 dba dba 4096 Jul 27 14:52 '#clone'
...
Er wird beim Starten der MySQL Datenbank automatisch entfernt. Wenn man ihn trotzdem löscht erhält man folgende Fehlermeldungen:
[System] [MY-013576] [InnoDB] InnoDB initialization has started.
[System] [MY-013577] [InnoDB] InnoDB initialization has ended.
mysqld: Can't create/write to file './performance_schema/clone_status_385.sdi' (OS errno 2 - No such file or directory)
mysqld: Can't create file './performance_schema/clone_status_385.sdi' (errno: 2 - No such file or directory)
[ERROR] [MY-013272] [Clone] Plugin Clone reported: 'Client: PFS table creation failed.'
[ERROR] [MY-010202] [Server] Plugin 'clone' init function returned error.
Die für das Point-in-Time-Recovery erforderliche Binary Log Position kann wie folgt ermittelt werden:
SQL> SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status;
+-------------------------------+-----------------+
| BINLOG_FILE | BINLOG_POSITION |
+-------------------------------+-----------------+
| boss_percona-84_binlog.000003 | 1231898 |
+-------------------------------+-----------------+
Remote Backup mittels Clone
Um einen remote Backup mittels der Clone-Funktionalität erstellen zu können braucht es eine minimal funktionale MySQL Datenbank auf dem remote System. Ein simpler Prozess/ein simples Tool reicht dazu leider nicht.
Auf dem Donor braucht es einen User mit den folgenden Privilegien:
SQL> CREATE USER 'backup_user'@'%' IDENTIFIED BY 'secret';
SQL> GRANT BACKUP_ADMIN ON *.* TO 'backup_user'@'%';
Zudem muss auf dem Recipient noch der mögliche Donor eingetragen werden:
SQL> SET GLOBAL clone_valid_donor_list = '192.168.1.129:3306';
Dann erfolgt das Backup remote wie folgt:
SQL> CLONE INSTANCE FROM 'backup_user'@'192.168.1.129':3306 IDENTIFIED BY 'secret'
DATA DIRECTORY = '/mnt/backup/mysql_clone';
Die weiter oben beschriebenen, noch fehlenden Dateien, müssen jetzt ebenfalls noch irgendwie kopiert werden:
$ scp mysql@192.168.1.129:${datadir}/*auto.cnf /mnt/backup/mysql_clone/
$ scp mysql@192.168.1.129:${datadir}/mysql_upgrade_history /mnt/backup/mysql_clone/
$ scp mysql@192.168.1.129:${datadir}/*.pem /mnt/backup/mysql_clone/
Das Wiederherstellen der Datenbank erfolgt analog zur Beschreibung oben.
Fazit
Die MySQL Clone-Operation ist ein cooles Feature, welches ich lange vernachlässigt habe, weil mir nicht in den Sinn kam, dass man es auch für Backzwecke nutzen könnte.
Es würde mich nicht wundern, wenn die MySQL Entwickler nach PostgreSQL pg_basebackup geschielt haben, als sie dieses Feature implementiert haben.
In MariaDB fehlt dieses Feature leider, meines Wissens, noch gänzlich. Schade!
Quellen
- Allgemein: The Clone Plugin
- Für das Clone-Backup gibt es einige wenige, minimale Einschränkungen, welche hier beschrieben sind: Clone Plugin Limitations.
- Das Überwachen des Clone-Backups ist hier beschrieben: Monitoring Cloning Operations.
- Das Tuning des Clone-Backups ist hier beschrieben: Clone System Variable Reference

