Replica di MySQL: lo slave è costantemente in ritardo rispetto al master


12

Sto usando MySQL-5.1.50 con una configurazione di replica Master-slave.

Il più delle volte lo schiavo è in ritardo rispetto al padrone.

Quando corro show processlist;, non ci sono query che richiedono molto tempo. Ho anche abilitato slow_log. Tuttavia, non trova alcuna query a esecuzione lenta.

Lo slave invia continuamente avvisi che la replica è secondi dietro il master. A volte, il tempo di ritardo aumenta.

Come posso diagnosticare la causa del problema?

Ho bisogno di un aiuto urgente, poiché questo problema è persistito negli ultimi 20 giorni.


Risposte:


20

Seconds_Behind_Master è davvero come guardare il passato attraverso i viaggi nel tempo.

Pensare in questo modo:

  • Il sole è 93.000.000 miglia di distanza dalla terra
  • La velocità della luce è 186.000 miglia / sec
  • La divisione semplice mostra che ci vogliono circa 500 sec (8 min 20 sec) affinché la luce del Sole raggiunga la Terra
  • Quando guardi il Sole, in realtà non vedi il Sole. Vedi dove era 8 min 20 sec fa.

Allo stesso modo, sembra che il Master stia elaborando molte query contemporaneamente.

SHOW SLAVE STATUS\GGuardi indietro allo Slave, corri e dice 200 per Seconds_Behind_Master. Come viene calcolato quel numero? Slave's Clock Time (UNIX_TIMESTAMP (NOW ()) - TIMESTAMP della query quando è stata completata e registrata nel registro binario del master.

C'è un'altra metrica da guardare oltre Seconds_Behind_Master. Si chiama quella metrica Relay_Log_Space. Ciò rappresenta la somma di tutti i byte per tutti i file di inoltro sullo slave. Per impostazione predefinita, il registro a relè singolo più grande è limitato a 1 GB. Se Relay_Log_Spaceè inferiore a 1 GB, ciò indica che molte query di lunga durata eseguite sul Master in parallelo. Sfortunatamente, a causa del thread SQL della replica a thread singolo, le query vengono eseguite una dietro l'altra.

Ad esempio, supponiamo di avere il seguente scenario sul Master:

  • Il registro delle query lente è abilitato
  • 20 query eseguite in parallelo sul Master
  • Ogni query ha richiesto 3 secondi
  • Ogni query viene registrata nel registro binario principale con lo stesso timestamp

Quando lo Slave legge quelle query dal suo registro di inoltro e le elabora una per una

  • l'orologio dello schiavo si muoverà
  • il TIMESTAMP per ciascuna delle 20 query sarà identico
  • la differenza aumenterà di 3 secondi per completare la query
  • questo si traduce in 60 secondi per Seconds_Behind_Master

Per quanto riguarda il registro lento, il valore predefinito per long_query_time è 10 secondi. Se tutte le tue query nei registri di inoltro sono inferiori a 10 secondi, non rileverai mai nulla nel registro delle query lente.

Ho i seguenti consigli per server Master e Slave

ULTERIORI RISOLUZIONE DEI PROBLEMI

Se si desidera visualizzare le query che causano il ritardo di sostituzione, attenersi alla seguente procedura:

  • SHOW SLAVE STATUS\G
  • Ottieni il nome del registro di inoltro da Relay_Log_File
  • STOP SLAVE;
  • START SLAVE;
  • Nel sistema operativo cd /var/lib/mysqlo ovunque siano scritti i registri di inoltro
  • Dump del registro di inoltro in un file di testo

Ad esempio, facciamolo 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

Se corro STOP SLAVE; START SLAVE;, il registro di inoltro si chiude e ne viene aperto uno nuovo. Eppure vuoi relay-bin.000030.

Scarica il contenuto come segue:

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

Ora puoi vedere le query che lo Slave sta attualmente cercando di elaborare. È possibile utilizzare tali query come punto di partenza per l'ottimizzazione.


A partire dalla v5.7, MySQL è in grado di applicare le modifiche agli slave in modalità multi-thread. La documentazione correlata è disponibile qui: dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html
edigu

2

Quale formato di registro binario stai usando? Stai usando ROW o STATEMENT?
" SHOW GLOBAL VARIABLES LIKE 'binlog_format';"

Se stai usando ROW come formato binlog assicurati che tutte le tue tabelle abbiano la chiave primaria o unica:
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;

Se si esegue, ad esempio, un'istruzione di eliminazione sul master per eliminare 1 milione di record su una tabella senza un PK o una chiave univoca, verrà eseguita solo una scansione della tabella completa sul lato master, che non è il caso sullo slave.
Quando viene utilizzato ROW binlog_format, MySQL scrive le modifiche delle righe nei log binari (non come un'istruzione come STATEMENT binlog_format) e tale modifica verrà applicata sul lato dello slave riga per riga, il che significa che verrà eseguita una scansione di 1 milione di tabelle complete sullo slave per riflettere solo un'istruzione di eliminazione sul master e ciò sta causando un problema di ritardo dello slave.


0

Il valore seconds_behind_master in SHOW SLAVE STATUS è la differenza tra l'ora di sistema sul master, che è stata memorizzata quando l'evento è stato originariamente eseguito e registrato nel registro binario ... e l'ora di sistema sullo slave quando l'evento viene eseguito lì.

I secondi dietro a master forniranno valori errati se i clock dei due sistemi non sono sincronizzati.


In MySQL 5.5 e versioni precedenti, l'esecuzione degli eventi di replica è a thread singolo sul lato slave. Dovrebbero esserci due thread in "SHOW FULL PROCESSLIST" in esecuzione come "utente di sistema": uno sta ricevendo eventi dal master, l'altro sta eseguendo le query. Se lo slave è in ritardo, quel thread dovrebbe mostrare quale query è attualmente in esecuzione. Dai un'occhiata a questo e guarda anche le statistiche del tuo disco / memoria / CPU per una fame di risorse.
Michael - sqlbot,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.