Wie man eine MySQL Replikation repariert

Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>

Wenn Du eine MySQL Replikation eingerichtet hast, kennst Du vielleicht folgendes Problem: Manchmal kommt es zu ungültigen MySQL Abfragen, die dafür sorgen, dass die Replikation nicht mehr funktioniert. In dieser Kurzanleitung werde ich zeigen, wie Du die Replikation auf dem MySQL Slave reparieren kannst, ohne sie von Neuem aufsetzen zu müssen.

Ich übernehme keine Garantie, dass dies auch bei Dir funktioniert!

1 Das Problem identifizieren

Um heruaszufinden, ob die Replikation funktioniert/nicht funktioniert und woran es liegt, warum sie nicht funktioniert, kannst Du Dir die Log-Dateien ansehen. Auf Debian zum Beipsiel loggt MySQL auf /var/log/syslog:

grep mysql /var/log/syslog

server1:/home/admin# grep mysql /var/log/syslog
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Slave: Error ‚Table ‚mydb.taggregate_temp_1212047760′ doesn’t exist‘ on query. Default database: ‚mydb‘. Query: ‚UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate
May 29 09:56:08 http2 mysqld[1380]: ^ISET thread.views = thread.views + aggregate.views
May 29 09:56:08 http2 mysqld[1380]: ^IWHERE thread.threadid = aggregate.threadid‘, Error_code: 1146
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with „SLAVE START“. We stopped at log ‚mysql-bin.001079‘ position 203015142
server1:/home/admin#

Du siehst welche Abfrage einen Fehler verursacht hat und auf welcher Log-Position die Replikation aufgehört hat.

Um nachzuprüfen, dass die Replikation wirklich nicht funktioniert, melde Dich bei MySQL an:

mysql -u root -p

Führe dies in der MySQL Kommandozeile aus:

mysql> SHOW SLAVE STATUS G

Wenn eines von Slave_IO_Running oder Slave_SQL_Running auf No gesetzt ist, dann ist die Replikation kaputt:

mysql> SHOW SLAVE STATUS G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 1.2.3.4
Master_User: slave_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.001079
Read_Master_Log_Pos: 269214454
Relay_Log_File: slave-relay.000130
Relay_Log_Pos: 100125935
Relay_Master_Log_File: mysql-bin.001079
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB: mydb
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1146
Last_Error: Error ‚Table ‚mydb.taggregate_temp_1212047760′ doesn’t exist‘ on query. Default database: ‚mydb‘.
Query: ‚UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate
SET thread.views = thread.views + aggregate.views
WHERE thread.threadid = aggregate.threadid‘
Skip_Counter: 0
Exec_Master_Log_Pos: 203015142
Relay_Log_Space: 166325247
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
1 row in set (0.00 sec)

mysql>

2 Die Replikation reparieren

Vergewissere Dich, dass wir den Slave gestoppt haben:

mysql> STOP SLAVE;

Die Problembehebung ist eigentlich ziemlich einfach. Wir teilen dem Slave einfach mit, dass er die ungültige SQL Abfrage überspringen soll:

mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;

Dies verursacht, dass der Slave eine Abfrage überspringt (die ungültige, die verursacht hat, dass die Replikation gestoppt worden ist). Wenn Du zwei Abfragen überspringen möchtest, musst Du stattdessen SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2; verwenden usw.

Das war es schon. Nun können wir den Slave erneut starten…

mysql> START SLAVE;

… und überprüfen, ob die Replikation wieder funktioniert:

mysql> SHOW SLAVE STATUS G

mysql> SHOW SLAVE STATUS G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 1.2.3.4
Master_User: slave_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.001079
Read_Master_Log_Pos: 447560366
Relay_Log_File: slave-relay.000130
Relay_Log_Pos: 225644062
Relay_Master_Log_File: mysql-bin.001079
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: mydb
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 447560366
Relay_Log_Space: 225644062
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)

mysql>

Wie Du siehst, ist Slave_IO_Running und Slave_SQL_Running jetzt auf Yes gesetzt.

Verlasse nun die MySQL Kommandozeile…

mysql> quit;

… und überprüfe erneut das Log:

grep mysql /var/log/syslog

server1:/home/admin# grep mysql /var/log/syslog
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Slave: Error ‚Table ‚mydb.taggregate_temp_1212047760′ doesn’t exist‘ on query. Default database: ‚mydb‘. Query: ‚UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate
May 29 09:56:08 http2 mysqld[1380]: ^ISET thread.views = thread.views + aggregate.views
May 29 09:56:08 http2 mysqld[1380]: ^IWHERE thread.threadid = aggregate.threadid‘, Error_code: 1146
May 29 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with „SLAVE START“. We stopped at log ‚mysql-bin.001079‘ position 203015142
May 29 11:42:13 http2 mysqld[1380]: 080529 11:42:13 [Note] Slave SQL thread initialized, starting replication in log ‚mysql-bin.001079‘ at position 203015142, relay log ‚/var/lib/mysql/slave-relay.000130‘ position: 100125935
server1:/home/admin#

Die letzte Zeile sagt, dass die Replikation wieder gestartet wurde. Wenn Du nach dieser Zeile keine Fehlermeldungen siehst, dann ist alles in Ordnung.

3 Links

Das könnte dich auch interessieren …