MySQL-Replikation - Slave bleibt ständig hinter dem Master zurück

11

Ich verwende MySQL-5.1.50 mit einem Master-Slave-Replikationssetup.

Meistens bleibt der Slave hinter dem Master zurück.

Wenn ich laufe show processlist;, gibt es keine Abfrage, die lange dauert. Ich habe auch aktiviert slow_log. Es wird jedoch keine langsam laufende Abfrage gefunden.

Der Slave gibt ständig Warnungen aus, dass die Replikation Sekunden hinter dem Master liegt. Manchmal erhöht sich die Verzögerungszeit.

Wie diagnostiziere ich die Ursache des Problems?

Ich brauche dringend Hilfe, da dieses Problem seit 20 Tagen besteht.

Adeela Sahar
quelle
Duplikat von stackoverflow.com/questions/8547827/…
Koustuv Chatterjee

Antworten:

19

Der Seconds_Behind_Master ist wirklich so, als würde man die Vergangenheit über Zeitreisen betrachten.

Denk darüber so:

  • Die Sonne ist 93.000.000 Meilen von der Erde entfernt
  • Die Lichtgeschwindigkeit beträgt 186.000 Meilen / Sek
  • Eine einfache Teilung zeigt, dass es ungefähr 500 Sekunden (8 Minuten 20 Sekunden) dauert, bis das Sonnenlicht die Erde erreicht
  • Wenn Sie auf die Sonne schauen, sehen Sie die Sonne tatsächlich nicht. Sie sehen, wo es vor 8 Minuten und 20 Sekunden war.

In ähnlicher Weise scheint es, dass der Master viele Anfragen gleichzeitig verarbeitet.

Du schaust zurück auf den Sklaven, rennst SHOW SLAVE STATUS\Gund es steht 200 für Seconds_Behind_Master. Wie wird diese Zahl berechnet? Slave's Clock Time (UNIX_TIMESTAMP (NOW ()) - TIMESTAMP der Abfrage, als sie abgeschlossen und im Binärprotokoll des Masters aufgezeichnet wurde.

Daneben gibt es noch eine andere Metrik Seconds_Behind_Master. Diese Metrik heißt Relay_Log_Space. Dies ist die Summe aller Bytes für alle Relay-Dateien auf dem Slave. Standardmäßig ist das größte einzelne Relay-Protokoll auf 1 GB begrenzt. Wenn Relay_Log_Spaceweniger als 1 GB vorhanden sind, bedeutet dies, dass viele lange laufende Abfragen parallel auf dem Master ausgeführt werden. Aufgrund des SQL-Threads der Replikation mit nur einem Thread werden Abfragen leider hintereinander ausgeführt.

Angenommen, Sie haben das folgende Szenario auf dem Master:

  • Das langsame Abfrageprotokoll ist aktiviert
  • 20 Abfragen werden parallel auf dem Master ausgeführt
  • Jede Abfrage dauerte 3 Sekunden
  • Jede Abfrage wird mit demselben Zeitstempel im Master-Binärprotokoll aufgezeichnet

Wenn der Slave diese Abfragen aus seinem Relay-Protokoll liest und einzeln verarbeitet

  • Die Sklavenuhr wird sich bewegen
  • Der TIMESTAMP für jede der 20 Abfragen ist identisch
  • Die Differenz erhöht sich um 3 Sekunden. Abfrage abgeschlossen
  • Dies ergibt 60 Sekunden für Seconds_Behind_Master

In Bezug auf das langsame Protokoll beträgt der Standardwert für long_query_time 10 Sekunden. Wenn alle Ihre Abfragen in den Relay-Protokollen weniger als 10 Sekunden dauern, werden Sie im Slow Query-Protokoll niemals etwas abfangen.

Ich habe die folgenden Empfehlungen für Master- und Slave-Server

WEITERE FEHLERSUCHE

Wenn Sie die Abfragen sehen möchten, die die Replikationsverzögerung verursachen, gehen Sie wie folgt vor:

  • SHOW SLAVE STATUS\G
  • Rufen Sie den Namen des Relay-Protokolls ab Relay_Log_File
  • STOP SLAVE;
  • START SLAVE;
  • Im Betriebssystem cd /var/lib/mysqloder überall dort , wo die Relay-Protokolle geschrieben werden
  • Speichern Sie das Relay-Protokoll in einer Textdatei

Zum Beispiel, lass es uns tun SHOW SLAVE STATUS\G

               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.64.51.149
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000009
          Read_Master_Log_Pos: 1024035856
               Relay_Log_File: relay-bin.000030
                Relay_Log_Pos: 794732078
        Relay_Master_Log_File: mysql-bin.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: search_cache
           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: 1024035856
              Relay_Log_Space: 794732271
              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
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 106451149

Wenn ich laufe STOP SLAVE; START SLAVE;, wird das Relaisprotokoll geschlossen und ein neues ist geöffnet. Trotzdem willst du relay-bin.000030.

Entleeren Sie den Inhalt wie folgt:

cd /var/lib/mysql
mysqlbinlog relay-bin.000030 > /root/RelayLogQueries.txt
less /root/RelayLogQueries.txt

Sie können jetzt die Abfragen sehen, die der Slave gerade zu verarbeiten versucht. Sie können diese Abfragen als Ausgangspunkt für die Optimierung verwenden.

RolandoMySQLDBA
quelle
Ab Version 5.7 kann MySQL Änderungen auf Multithread-Weise auf Slaves anwenden. Zugehörige Dokumentationen finden Sie hier: dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html
edigu
2

Welches binäre Protokollformat verwenden Sie? Verwenden Sie ROW oder STATEMENT?
" SHOW GLOBAL VARIABLES LIKE 'binlog_format';"

Wenn Sie ROW als Binlog-Format verwenden, stellen Sie sicher, dass alle Ihre Tabellen über einen Primär- oder einen eindeutigen Schlüssel verfügen:
SELECT t.table_schema,t.table_name,engine FROM information_schema.tables t INNER JOIN information_schema .columns c on t.table_schema=c.table_schema and t.table_name=c.table_name and t.table_schema not in ('performance_schema','information_schema','mysql') GROUP BY t.table_schema,t.table_name HAVING sum(if(column_key in ('PRI','UNI'), 1,0)) =0;

Wenn Sie beispielsweise eine Löschanweisung auf dem Master ausführen, um 1 Million Datensätze in einer Tabelle ohne PK oder eindeutigen Schlüssel zu löschen, findet auf der Masterseite nur ein vollständiger Tabellenscan statt, was auf dem Slave nicht der Fall ist.
Wenn ROW binlog_format verwendet wird, schreibt MySQL die Zeilenänderungen in die Binärprotokolle (nicht als Anweisung wie STATEMENT binlog_format) und diese Änderung wird zeilenweise auf die Seite des Slaves angewendet, was bedeutet, dass ein 1-Millionen-vollständiger Tabellenscan durchgeführt wird Wenn der Slave nur eine Löschanweisung auf dem Master wiedergibt, führt dies zu einem Problem mit der Verzögerung des Slaves.

Moll
quelle
0

Der Wert von second_behind_master in SHOW SLAVE STATUS ist die Differenz zwischen der Systemzeit auf dem Master, die gespeichert wurde, als das Ereignis ursprünglich ausgeführt und im Binärprotokoll aufgezeichnet wurde ... und der Systemzeit auf dem Slave, wenn das Ereignis dort ausgeführt wird.

Sekunden hinter dem Master geben falsche Werte aus, wenn die Uhren der beiden Systeme nicht synchron sind.

Michael - sqlbot
quelle
In MySQL 5.5 und früheren Versionen erfolgt die Ausführung von Replikationsereignissen auf der Slave-Seite mit einem Thread. In "SHOW FULL PROCESSLIST" sollten zwei Threads als "Systembenutzer" ausgeführt werden - einer empfängt Ereignisse vom Master, der andere führt die Abfragen aus. Wenn der Slave hinterherhinkt, sollte dieser Thread anzeigen, welche Abfrage gerade ausgeführt wird. Schauen Sie sich das an und sehen Sie sich auch Ihre Festplatten- / Speicher- / CPU-Statistiken an, um einen Ressourcenmangel festzustellen.
Michael - sqlbot