MariaDB
 sql >> Datenbank >  >> RDS >> MariaDB

Mehrere verzögerte Replikations-Slaves für Disaster Recovery mit niedrigem RTO

Die verzögerte Replikation ermöglicht es einem Replikations-Slave, dem Master absichtlich um mindestens eine bestimmte Zeitspanne hinterherzuhinken. Vor der Ausführung eines Events wartet der Slave ggf. zunächst, bis die vorgegebene Zeit verstrichen ist, seit das Event auf dem Master erzeugt wurde. Das Ergebnis ist, dass der Slave den Zustand des Masters vor einiger Zeit in der Vergangenheit widerspiegelt. Diese Funktion wird seit MySQL 5.6 und MariaDB 10.2.3 unterstützt. Es kann sich im Falle einer versehentlichen Datenlöschung als nützlich erweisen und sollte Teil Ihres Disaster-Recovery-Plans sein.

Das Problem beim Einrichten eines verzögerten Replikations-Slaves ist, wie viel Verzögerung wir einplanen sollten. Zu wenig Zeit und Sie riskieren, dass die schlechte Abfrage zu Ihrem verspäteten Sklaven gelangt, bevor Sie ihn erreichen können, und verschwenden so den Sinn, den verspäteten Sklaven zu haben. Optional können Sie Ihre verzögerte Zeit so lang machen, dass es Stunden dauert, bis Ihr verspäteter Slave dort aufholt, wo der Master zum Zeitpunkt des Fehlers war.

Glücklicherweise ist die Prozessisolierung von Docker seine Stärke. Das Ausführen mehrerer MySQL-Instanzen ist mit Docker ziemlich praktisch. Es ermöglicht uns, mehrere verzögerte Slaves in einem einzigen physischen Host zu haben, um unsere Wiederherstellungszeit zu verbessern und Hardwareressourcen zu sparen. Wenn Sie der Meinung sind, dass eine Verzögerung von 15 Minuten zu kurz ist, können wir eine weitere Instanz mit einer Verzögerung von 1 Stunde oder 6 Stunden für einen noch älteren Snapshot unserer Datenbank erstellen.

In diesem Blogbeitrag werden wir mehrere verzögerte MySQL-Slaves auf einem einzigen physischen Host mit Docker bereitstellen und einige Wiederherstellungsszenarien zeigen. Das folgende Diagramm veranschaulicht unsere endgültige Architektur, die wir erstellen möchten:

Unsere Architektur besteht aus einer bereits bereitgestellten 2-Knoten-MySQL-Replikation, die auf physischen Servern (blau) ausgeführt wird, und wir möchten weitere drei MySQL-Slaves (grün) mit folgendem Verhalten einrichten:

  • 15 Minuten Verspätung
  • 1 Stunde Verspätung
  • 6 Stunden Verspätung

Beachten Sie, dass wir 3 Kopien genau derselben Daten auf demselben physischen Server haben werden. Stellen Sie sicher, dass unser Docker-Host über den erforderlichen Speicherplatz verfügt, weisen Sie also im Voraus ausreichend Speicherplatz zu.

MySQL-Master-Vorbereitung

Melden Sie sich zunächst beim Masterserver an und erstellen Sie den Replikationsbenutzer:

mysql> GRANT REPLICATION SLAVE ON *.* TO [email protected]'%' IDENTIFIED BY 'YlgSH6bLLy';

Erstellen Sie dann ein PITR-kompatibles Backup auf dem Master:

$ mysqldump -uroot -p --flush-privileges --hex-blob --opt --master-data=1 --single-transaction --skip-lock-tables --skip-lock-tables --triggers --routines --events --all-databases | gzip -6 -c > mysqldump_complete.sql.gz

Wenn Sie ClusterControl verwenden, können Sie ganz einfach ein PITR-kompatibles Backup erstellen. Gehen Sie zu Backups -> Backup erstellen und wählen Sie „Complete PITR-compatible“ unter der Dropdown-Liste „Dump Type“:

Übertragen Sie diese Sicherung schließlich auf den Docker-Host:

$ scp mysqldump_complete.sql.gz [email protected]:~

Diese Sicherungsdatei wird von den MySQL-Slave-Containern während des Slave-Bootstrapping-Prozesses verwendet, wie im nächsten Abschnitt gezeigt wird.

Verzögerte Slave-Bereitstellung

Bereiten Sie unsere Docker-Containerverzeichnisse vor. Erstellen Sie 3 Verzeichnisse (mysql.conf.d, datadir und sql) für jeden MySQL-Container, den wir starten werden (Sie können loop verwenden, um die folgenden Befehle zu vereinfachen):

$ mkdir -p /storage/mysql-slave-15m/mysql.conf.d
$ mkdir -p /storage/mysql-slave-15m/datadir
$ mkdir -p /storage/mysql-slave-15m/sql
$ mkdir -p /storage/mysql-slave-1h/mysql.conf.d
$ mkdir -p /storage/mysql-slave-1h/datadir
$ mkdir -p /storage/mysql-slave-1h/sql
$ mkdir -p /storage/mysql-slave-6h/mysql.conf.d
$ mkdir -p /storage/mysql-slave-6h/datadir
$ mkdir -p /storage/mysql-slave-6h/sql

Das Verzeichnis „mysql.conf.d“ speichert unsere benutzerdefinierte MySQL-Konfigurationsdatei und wird dem Container unter /etc/mysql.conf.d zugeordnet. „datadir“ ist der Ort, an dem Docker das MySQL-Datenverzeichnis speichern soll, das /var/lib/mysql des Containers zugeordnet ist, und das „sql“-Verzeichnis speichert unsere SQL-Dateien – Sicherungsdateien im .sql- oder .sql.gz-Format zum Staging den Slave vor der Replikation und auch .sql-Dateien, um die Replikationskonfiguration und den Start zu automatisieren.

15 Minuten verzögerter Sklave

Bereiten Sie die MySQL-Konfigurationsdatei für unseren 15-Minuten-verspäteten Slave vor:

$ vim /storage/mysql-slave-15m/mysql.conf.d/my.cnf

Und fügen Sie die folgenden Zeilen hinzu:

[mysqld]
server_id=10015
binlog_format=ROW
log_bin=binlog
log_slave_updates=1
gtid_mode=ON
enforce_gtid_consistency=1
relay_log=relay-bin
expire_logs_days=7
read_only=ON

** Der Server-ID-Wert, den wir für diesen Slave verwendet haben, ist 10015.

Als nächstes erstellen Sie im Verzeichnis /storage/mysql-slave-15m/sql zwei SQL-Dateien, eine zum RESET MASTER (1reset_master.sql) und eine weitere zum Herstellen der Replikationsverbindung mit der CHANGE MASTER-Anweisung (3setup_slave.sql).

Erstellen Sie eine Textdatei 1reset_master.sql und fügen Sie die folgende Zeile hinzu:

RESET MASTER;

Erstellen Sie eine Textdatei 3setup_slave.sql und fügen Sie die folgenden Zeilen hinzu:

CHANGE MASTER TO MASTER_HOST = '192.168.55.171', MASTER_USER = 'rpl_user', MASTER_PASSWORD = 'YlgSH6bLLy', MASTER_AUTO_POSITION = 1, MASTER_DELAY=900;
START SLAVE;

MASTER_DELAY=900 entspricht 15 Minuten (in Sekunden). Kopieren Sie dann die von unserem Master entnommene Sicherungsdatei (die in unseren Docker-Host übertragen wurde) in das Verzeichnis „sql“ und benennen Sie sie in 2mysqldump_complete.sql.gz um:

$ cp ~/mysqldump_complete.tar.gz /storage/mysql-slave-15m/sql/2mysqldump_complete.tar.gz

Das endgültige Aussehen unseres "sql"-Verzeichnisses sollte in etwa so aussehen:

$ pwd
/storage/mysql-slave-15m/sql
$ ls -1
1reset_master.sql
2mysqldump_complete.sql.gz
3setup_slave.sql

Beachten Sie, dass wir dem SQL-Dateinamen eine ganze Zahl voranstellen, um die Ausführungsreihenfolge festzulegen, wenn Docker den MySQL-Container initialisiert.

Sobald alles eingerichtet ist, führen Sie den MySQL-Container für unseren 15-Minuten-verspäteten Slave aus:

$ docker run -d \
--name mysql-slave-15m \
-e MYSQL_ROOT_PASSWORD=password \
--mount type=bind,source=/storage/mysql-slave-15m/datadir,target=/var/lib/mysql \
--mount type=bind,source=/storage/mysql-slave-15m/mysql.conf.d,target=/etc/mysql/mysql.conf.d \
--mount type=bind,source=/storage/mysql-slave-15m/sql,target=/docker-entrypoint-initdb.d \
mysql:5.7

** Der MYSQL_ROOT_PASSWORD-Wert muss mit dem MySQL-Root-Passwort auf dem Master identisch sein.

Die folgenden Zeilen suchen wir, um zu überprüfen, ob MySQL korrekt läuft und als Slave mit unserem Master (192.168.55.171) verbunden ist:

$ docker logs -f mysql-slave-15m
...
2018-12-04T04:05:24.890244Z 0 [Note] mysqld: ready for connections.
Version: '5.7.24-log'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2018-12-04T04:05:25.010032Z 2 [Note] Slave I/O thread for channel '': connected to master '[email protected]:3306',replication started in log 'FIRST' at position 4

Sie können dann den Replikationsstatus mit der folgenden Anweisung überprüfen:

$ docker exec -it mysql-slave-15m mysql -uroot -p -e 'show slave status\G'
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
                    SQL_Delay: 900
                Auto_Position: 1
...

An diesem Punkt wird unser 15-Minuten-verzögerter Slave-Container korrekt repliziert und unsere Architektur sieht in etwa so aus:

1 Stunde verzögerter Slave

Bereiten Sie die MySQL-Konfigurationsdatei für unseren um eine Stunde verzögerten Slave vor:

$ vim /storage/mysql-slave-1h/mysql.conf.d/my.cnf

Und fügen Sie die folgenden Zeilen hinzu:

[mysqld]
server_id=10060
binlog_format=ROW
log_bin=binlog
log_slave_updates=1
gtid_mode=ON
enforce_gtid_consistency=1
relay_log=relay-bin
expire_logs_days=7
read_only=ON

** Der Server-ID-Wert, den wir für diesen Slave verwendet haben, ist 10060.

Erstellen Sie als Nächstes im Verzeichnis /storage/mysql-slave-1h/sql zwei SQL-Dateien, eine für RESET MASTER (1reset_master.sql) und eine andere, um die Replikationsverbindung mit der CHANGE MASTER-Anweisung (3setup_slave.sql) herzustellen.

Erstellen Sie eine Textdatei 1reset_master.sql und fügen Sie die folgende Zeile hinzu:

RESET MASTER;

Erstellen Sie eine Textdatei 3setup_slave.sql und fügen Sie die folgenden Zeilen hinzu:

CHANGE MASTER TO MASTER_HOST = '192.168.55.171', MASTER_USER = 'rpl_user', MASTER_PASSWORD = 'YlgSH6bLLy', MASTER_AUTO_POSITION = 1, MASTER_DELAY=3600;
START SLAVE;

MASTER_DELAY=3600 entspricht 1 Stunde (in Sekunden). Kopieren Sie dann die von unserem Master entnommene Sicherungsdatei (die in unseren Docker-Host übertragen wurde) in das Verzeichnis „sql“ und benennen Sie sie in 2mysqldump_complete.sql.gz um:

$ cp ~/mysqldump_complete.tar.gz /storage/mysql-slave-1h/sql/2mysqldump_complete.tar.gz

Das endgültige Aussehen unseres "sql"-Verzeichnisses sollte in etwa so aussehen:

$ pwd
/storage/mysql-slave-1h/sql
$ ls -1
1reset_master.sql
2mysqldump_complete.sql.gz
3setup_slave.sql

Beachten Sie, dass wir dem SQL-Dateinamen eine ganze Zahl voranstellen, um die Ausführungsreihenfolge festzulegen, wenn Docker den MySQL-Container initialisiert.

Sobald alles eingerichtet ist, führen Sie den MySQL-Container für unseren um eine Stunde verzögerten Slave aus:

$ docker run -d \
--name mysql-slave-1h \
-e MYSQL_ROOT_PASSWORD=password \
--mount type=bind,source=/storage/mysql-slave-1h/datadir,target=/var/lib/mysql \
--mount type=bind,source=/storage/mysql-slave-1h/mysql.conf.d,target=/etc/mysql/mysql.conf.d \
--mount type=bind,source=/storage/mysql-slave-1h/sql,target=/docker-entrypoint-initdb.d \
mysql:5.7

** Der MYSQL_ROOT_PASSWORD-Wert muss mit dem MySQL-Root-Passwort auf dem Master identisch sein.

Die folgenden Zeilen suchen wir, um zu überprüfen, ob MySQL korrekt läuft und als Slave mit unserem Master (192.168.55.171) verbunden ist:

$ docker logs -f mysql-slave-1h
...
2018-12-04T04:05:24.890244Z 0 [Note] mysqld: ready for connections.
Version: '5.7.24-log'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2018-12-04T04:05:25.010032Z 2 [Note] Slave I/O thread for channel '': connected to master '[email protected]:3306',replication started in log 'FIRST' at position 4

Sie können dann den Replikationsstatus mit der folgenden Anweisung überprüfen:

$ docker exec -it mysql-slave-1h mysql -uroot -p -e 'show slave status\G'
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
                    SQL_Delay: 3600
                Auto_Position: 1
...

An diesem Punkt replizieren unsere 15 Minuten und 1 Stunde MySQL verzögerten Slave-Container vom Master und unsere Architektur sieht etwa so aus:

6 Stunden verspäteter Sklave

Bereiten Sie die MySQL-Konfigurationsdatei für unseren 6-Stunden-verspäteten Slave vor:

$ vim /storage/mysql-slave-15m/mysql.conf.d/my.cnf

Und fügen Sie die folgenden Zeilen hinzu:

[mysqld]
server_id=10006
binlog_format=ROW
log_bin=binlog
log_slave_updates=1
gtid_mode=ON
enforce_gtid_consistency=1
relay_log=relay-bin
expire_logs_days=7
read_only=ON

** Der Server-ID-Wert, den wir für diesen Slave verwendet haben, ist 10006.

Erstellen Sie als Nächstes im Verzeichnis /storage/mysql-slave-6h/sql zwei SQL-Dateien, eine zum RESET MASTER (1reset_master.sql) und eine weitere zum Herstellen der Replikationsverbindung mit der CHANGE MASTER-Anweisung (3setup_slave.sql).

Erstellen Sie eine Textdatei 1reset_master.sql und fügen Sie die folgende Zeile hinzu:

RESET MASTER;

Erstellen Sie eine Textdatei 3setup_slave.sql und fügen Sie die folgenden Zeilen hinzu:

CHANGE MASTER TO MASTER_HOST = '192.168.55.171', MASTER_USER = 'rpl_user', MASTER_PASSWORD = 'YlgSH6bLLy', MASTER_AUTO_POSITION = 1, MASTER_DELAY=21600;
START SLAVE;

MASTER_DELAY=21600 entspricht 6 Stunden (in Sekunden). Kopieren Sie dann die von unserem Master entnommene Sicherungsdatei (die in unseren Docker-Host übertragen wurde) in das Verzeichnis „sql“ und benennen Sie sie in 2mysqldump_complete.sql.gz um:

$ cp ~/mysqldump_complete.tar.gz /storage/mysql-slave-6h/sql/2mysqldump_complete.tar.gz

Das endgültige Aussehen unseres "sql"-Verzeichnisses sollte in etwa so aussehen:

$ pwd
/storage/mysql-slave-6h/sql
$ ls -1
1reset_master.sql
2mysqldump_complete.sql.gz
3setup_slave.sql

Beachten Sie, dass wir dem SQL-Dateinamen eine ganze Zahl voranstellen, um die Ausführungsreihenfolge festzulegen, wenn Docker den MySQL-Container initialisiert.

Sobald alles eingerichtet ist, führen Sie den MySQL-Container für unseren 6-Stunden-verspäteten Slave aus:

$ docker run -d \
--name mysql-slave-6h \
-e MYSQL_ROOT_PASSWORD=password \
--mount type=bind,source=/storage/mysql-slave-6h/datadir,target=/var/lib/mysql \
--mount type=bind,source=/storage/mysql-slave-6h/mysql.conf.d,target=/etc/mysql/mysql.conf.d \
--mount type=bind,source=/storage/mysql-slave-6h/sql,target=/docker-entrypoint-initdb.d \
mysql:5.7

** Der MYSQL_ROOT_PASSWORD-Wert muss mit dem MySQL-Root-Passwort auf dem Master identisch sein.

Die folgenden Zeilen suchen wir, um zu überprüfen, ob MySQL korrekt läuft und als Slave mit unserem Master (192.168.55.171) verbunden ist:

$ docker logs -f mysql-slave-6h
...
2018-12-04T04:05:24.890244Z 0 [Note] mysqld: ready for connections.
Version: '5.7.24-log'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2018-12-04T04:05:25.010032Z 2 [Note] Slave I/O thread for channel '': connected to master '[email protected]:3306',replication started in log 'FIRST' at position 4

Sie können dann den Replikationsstatus mit der folgenden Anweisung überprüfen:

$ docker exec -it mysql-slave-6h mysql -uroot -p -e 'show slave status\G'
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
                    SQL_Delay: 21600
                Auto_Position: 1
...

An diesem Punkt werden unsere Slave-Container mit 5 Minuten, 1 Stunde und 6 Stunden Verzögerung korrekt repliziert, und unsere Architektur sieht in etwa so aus:

Disaster-Recovery-Szenario

Angenommen, ein Benutzer hat versehentlich eine falsche Spalte auf einer großen Tabelle abgelegt. Stellen Sie sich vor, die folgende Anweisung wurde auf dem Master ausgeführt:

mysql> USE shop;
mysql> ALTER TABLE settings DROP COLUMN status;

Wenn Sie das Glück haben, es sofort zu erkennen, können Sie den 15-Minuten-verspäteten Slave verwenden, um den Moment vor der Katastrophe aufzuholen und ihn zum Master zu machen, oder die fehlenden Daten exportieren und auf dem Master wiederherstellen.

Erstens müssen wir die Position des Binärlogs finden, bevor die Katastrophe passiert ist. Holen Sie sich die Zeit jetzt() auf dem Master:

mysql> SELECT now();
+---------------------+
| now()               |
+---------------------+
| 2018-12-04 14:55:41 |
+---------------------+

Holen Sie sich dann die aktive binäre Protokolldatei auf dem Master:

mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                                                                                                                     |
+---------------+----------+--------------+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| binlog.000004 | 20260658 |              |                  | 1560665e-ed2b-11e8-93fa-000c29b7f985:1-12031,
1b235f7a-d37b-11e8-9c3e-000c29bafe8f:1-62519,
1d8dc60a-e817-11e8-82ff-000c29bafe8f:1-326575,
791748b3-d37a-11e8-b03a-000c29b7f985:1-374 |
+---------------+----------+--------------+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Extrahieren Sie mit demselben Datumsformat die gewünschten Informationen aus dem Binärlog binlog.000004. Wir schätzen die Startzeit zum Lesen aus dem Binlog vor etwa 20 Minuten (2018-12-04 14:35:00) und filtern die Ausgabe so, dass 25 Zeilen vor der Anweisung „drop column“ angezeigt werden:

$ mysqlbinlog --start-datetime="2018-12-04 14:35:00" --stop-datetime="2018-12-04 14:55:41" /var/lib/mysql/binlog.000004 | grep -i -B 25 "drop column"
'/*!*/;
# at 19379172
#181204 14:54:45 server id 1  end_log_pos 19379232 CRC32 0x0716e7a2     Table_map: `shop`.`settings` mapped to number 766
# at 19379232
#181204 14:54:45 server id 1  end_log_pos 19379460 CRC32 0xa6187edd     Write_rows: table id 766 flags: STMT_END_F

BINLOG '
tSQGXBMBAAAAPAAAACC0JwEAAP4CAAAAAAEABnNidGVzdAAHc2J0ZXN0MgAFAwP+/gME/nj+PBCi
5xYH
tSQGXB4BAAAA5AAAAAS1JwEAAP4CAAAAAAEAAgAF/+AYwwAAysYAAHc0ODYyMjI0NjI5OC0zNDE2
OTY3MjY5OS02MDQ1NTQwOTY1Ny01MjY2MDQ0MDcwOC05NDA0NzQzOTUwMS00OTA2MTAxNzgwNC05
OTIyMzM3NzEwOS05NzIwMzc5NTA4OC0yODAzOTU2NjQ2MC0zNzY0ODg3MTYzOTswMTM0MjAwNTcw
Ni02Mjk1ODMzMzExNi00NzQ1MjMxODA1OS0zODk4MDQwMjk5MS03OTc4MTA3OTkwNQEAAADdfhim
'/*!*/;
# at 19379460
#181204 14:54:45 server id 1  end_log_pos 19379491 CRC32 0x71f00e63     Xid = 622405
COMMIT/*!*/;
# at 19379491
#181204 14:54:46 server id 1  end_log_pos 19379556 CRC32 0x62b78c9e     GTID    last_committed=11507    sequence_number=11508   rbr_only=no
SET @@SESSION.GTID_NEXT= '1560665e-ed2b-11e8-93fa-000c29b7f985:11508'/*!*/;
# at 19379556
#181204 14:54:46 server id 1  end_log_pos 19379672 CRC32 0xc222542a     Query   thread_id=3162  exec_time=1     error_code=0
SET TIMESTAMP=1543906486/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
ALTER TABLE settings DROP COLUMN status

In den unteren Zeilen der mysqlbinlog-Ausgabe sollten Sie den fehlerhaften Befehl haben, der an Position 19379556 ausgeführt wurde. Die Position, die wir wiederherstellen sollten, ist einen Schritt davor, nämlich Position 19379491. Dies ist die Binlog-Position, an der wir unsere haben möchten verspäteter Sklave bis zu.

Stoppen Sie dann auf dem ausgewählten verzögerten Slave den verzögerten Replikations-Slave und starten Sie den Slave erneut an einer festen Endposition, die wir oben herausgefunden haben:

$ docker exec -it mysql-slave-15m mysql -uroot -p
mysql> STOP SLAVE;
mysql> START SLAVE UNTIL MASTER_LOG_FILE = 'binlog.000004', MASTER_LOG_POS = 19379491;

Überwachen Sie den Replikationsstatus und warten Sie, bis Exec_Master_Log_Pos gleich dem Wert Until_Log_Pos ist. Dies kann einige Zeit dauern. Sobald Sie aufgeholt haben, sollten Sie Folgendes sehen:

$ docker exec -it mysql-slave-15m mysql -uroot -p -e 'SHOW SLAVE STATUS\G'
... 
          Exec_Master_Log_Pos: 19379491
              Relay_Log_Space: 50552186
              Until_Condition: Master
               Until_Log_File: binlog.000004
                Until_Log_Pos: 19379491
...

Überprüfen Sie abschließend, ob die fehlenden Daten, nach denen wir gesucht haben, vorhanden sind (Spalte "Status" existiert noch):

mysql> DESCRIBE shop.settings;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| sid    | int(10) unsigned | NO   | MUL | 0       |                |
| param  | varchar(100)     | NO   |     |         |                |
| value  | varchar(255)     | NO   |     |         |                |
| status | int(11)          | YES  |     | 1       |                |
+--------+------------------+------+-----+---------+----------------+

Exportieren Sie dann die Tabelle aus unserem Slave-Container und übertragen Sie sie auf den Master-Server:

$ docker exec -it mysql-slave-1h mysqldump -uroot -ppassword --single-transaction shop settings > shop_settings.sql

Löschen Sie die problematische Tabelle und stellen Sie sie auf dem Master wieder her:

$ mysql -uroot -p -e 'DROP TABLE shop.settings'
$ mysqldump -uroot -p -e shop < shop_setttings.sql

Wir haben unseren Tisch jetzt wieder in seinen ursprünglichen Zustand vor dem katastrophalen Ereignis zurückversetzt. Zusammenfassend lässt sich sagen, dass die verzögerte Replikation für mehrere Zwecke verwendet werden kann:

  • Zum Schutz vor Benutzerfehlern auf dem Master. Ein DBA kann einen verzögerten Slave auf die Zeit kurz vor der Katastrophe zurücksetzen.
  • Um zu testen, wie sich das System verhält, wenn es eine Verzögerung gibt. Beispielsweise kann in einer Anwendung eine Verzögerung durch eine starke Belastung des Slaves verursacht werden. Es kann jedoch schwierig sein, dieses Lastniveau zu erzeugen. Verzögerte Replikation kann die Verzögerung simulieren, ohne die Last simulieren zu müssen. Es kann auch verwendet werden, um Bedingungen zu debuggen, die sich auf einen nacheilenden Slave beziehen.
  • Inspizieren, wie die Datenbank in der Vergangenheit aussah, ohne ein Backup neu laden zu müssen. Wenn die Verzögerung beispielsweise eine Woche beträgt und der DBA sehen muss, wie die Datenbank vor den letzten Tagen der Entwicklung aussah, kann der verzögerte Slave inspiziert werden.

Abschließende Gedanken

Mit Docker können mehrere MySQL-Instanzen auf demselben physischen Host effizient ausgeführt werden. Sie können Docker-Orchestrierungstools wie Docker Compose und Swarm verwenden, um die Multi-Container-Bereitstellung im Gegensatz zu den in diesem Blogbeitrag gezeigten Schritten zu vereinfachen.