Cosa causa l'errore MySQL 1062: voce duplicata all'avvio dello slave?


11
  • Versione MySQL Master: 5.5.16-1
  • Versione di MySQL Slave: 5.5.18-1

Lo snapshot del master è creato da:

mysql> FLUSH TABLES WITH READ LOCK;
shell> mysqldump --all-databases --master-data > dbname_`date +%F`.sql

Questo file di dump viene importato sullo slave (che viene avviato con l' --skip-slave-startopzione) senza errori:

shell> pv dbname_`date +%F`.sql | mysql -u root -p

Ma ho visualizzato il seguente errore durante l'esecuzione di mysql> start slave;:

    Last_SQL_Errno: 1062
    Last_SQL_Error: Error 'Duplicate entry '115846' for key
'PRIMARY'' on query. Default database: 'db'. Query: 'INSERT INTO
request_posted (id, user_id, channel, message, link, picture, name, ...

Esiste un solo record con ID 115846 sul master:

mysql> select count(*) from request_posted where id=115846;
Current database: db

+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.01 sec)

Prova a saltare alcune query con:

mysql> STOP SLAVE; 
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; 
mysql> START SLAVE;

non ha aiutato. Non voglio saltare quegli errori aggiungendo:

slave-skip-errors = 1062

al my.cnffile perché può portare incoerente allo slave.

Quale può essere la ragione di questo errore?


AGGIORNARE

Non è così che di solito installo la replica mySQL

Quali passi pensi che non segua il documento?

Mi chiedo se incontrerai lo stesso problema se dovessi impostare l'intera configurazione piuttosto che passare il comando mysqldump.

No, funziona normalmente se cambio anche il master in coordinate corrispondenti.

Vorrei provare a far cadere il database sullo slave, assicurarsi che i binlog siano chiari e ricominciare. Controlla anche la tabella in questione sul master per assicurarti che gli indici non abbiano errori.

Elimina (sposta) tutto il datadir è sufficiente? L'ho fatto e ho ottenuto lo stesso risultato.


Rispondi a @Dmytro Leonenko

'mostra stato slave \ G' sullo slave per assicurarsi che sia configurato correttamente, MASTER_LOG_POS è 0

Solo 'show slave statug \ G' dopo l'importazione ma prima di 'start slave;' può darci la risposta

Ho eseguito il backup del datadir, cancellato tutto ed eseguito mysql_install_db, importato il file di dump, eseguito change master toed ecco i risultati:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: x.x.x.x
                  Master_User: xx
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: 
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: 
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          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: 0
              Relay_Log_Space: 106
              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
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
1 row in set (0.00 sec)

Mi chiedo perché Master_Log_Pos è 4?


1
Ci può essere solo un record con quell'id, quindi l'errore, non verrà mai scritto. Quando si emette SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1La query che causa l'errore cambia almeno? La posizione del binlog slave è stata impostata correttamente?
thinice

Ogni volta che salto il contatore, cambia in un altro ID. L' --master-dataopzione è già scrivere le coordinate del registro binario nel file di dump. Devo solo cambiare master in master_host, master_user, master_password.
quanta

Questo non è il modo in cui di solito installo la replica mySQL (generalmente installo la replica per URL qui: dev.mysql.com/doc/refman/5.0/en/replication-howto.html ) Tuttavia, leggendo le opzioni di mysqldump, non c'è motivo perché non dovrebbe funzionare. Mi chiedo se incontrerai lo stesso problema se dovessi impostare l'intera configurazione piuttosto che passare il comando mysqldump.
Rilindo,

Vuoi dire che non dovrei usare l' --master-dataopzione durante la creazione di un'istantanea dei dati? Se succede ancora quando uso l' --lock-all-tablesopzione e change master to master_log_file='', master_log_pos='', ..., quali possono essere le cause?
quanta

No, non è quello che sto dicendo. Come ho accennato, ciò che hai fatto dovrebbe funzionare come previsto - per quanto posso vedere, non esiste alcun bug esistente con questa opzione. Tuttavia, ciò non significa che non ci sia, quindi come passaggio di isolamento, seguirò prima la convenzione fornita da mySQL tramite quell'URL. t. Se funziona, almeno hai la direzione per iniziare la risoluzione dei problemi. In caso contrario, abbiamo un problema diverso. :)
Rilindo,

Risposte:


7

Cosa provare a risolvere il tuo problema:

  1. È necessario rimuovere prima master.info sullo slave e riavviare mysql
  2. problema CAMBIA MASTER A MASTER_HOST = 'XX.XX.XX.XX', MASTER_USER = 'repl', MASTER_PASSWORD = 'slavepass';
  3. fare mysqldump con l'opzione '--flush-logs' sul master
  4. 'mysql -u user -p <dump.sql' sullo slave
  5. 'mostra stato slave \ G' sullo slave per assicurarsi che sia configurato correttamente, MASTER_LOG_POS è 0
  6. 'avvia schiavo;' sullo schiavo.

Cosa controllare anche:

  • Formato binlog: MISTO
  • server_ids sono diversi su master e slave

L'emissione dell'intera stringa principale di modifica (incluso il nome del registro e il numero di posizione) in realtà la risolve, ma a questo punto, penso che la domanda principale sia perché Quanta deve reinserire il nome di registro e il numero di posizione quando questo è già nel File spazzatura.
Rilindo,

Solo 'show slave statug \ G' dopo l'importazione ma prima di 'start slave;' ci può dare la risposta
Dmytro Leonenko l'

ho aggiunto le informazioni richieste al mio post originale.
quanta

Come sei finito con "Master_Host: xxxx Master_User: xx" senza emettere "CHANGE MASTER ...". O non l'hai appena menzionato in risposta? Hai controllato il formato binlog e qual era la riga di comando per mysqldump?
Dmytro Leonenko,

Ho già detto che nel mio post " importa il file di dump, eseguichange master to ". Sto utilizzando la registrazione basata su MIXED. Ho provato con MySQL 5.0.77 (basato su istruzioni), causa anche questo errore. Il mysqldump completo èmysqldump -u root -p --all-databases --master-data --flush-logs > alldb_$(date +%F).sql
quanta

2

Il problema è causato dall'impostazione del master su un server di produzione in esecuzione PRIMA di eseguire il dump (per quanto ne so). Quindi, ci sono query scritte nel master_log che sono già state eseguite sui dati che risiedono sullo slave. In realtà non ho mai visto una soluzione sul sito Web mysql o sulla mailing list. Quindi, ho trovato la seguente soluzione che ha risolto il mio problema.

sullo schiavo:

mysql> STOP SLAVE;
mysql> FLUSH PRIVILEGES;  # dump likly included users too

sul maestro:

mysql> RESET MASTER;

sullo schiavo:

mysql> RESET SLAVE;
mysql> START SLAVE;

a proposito, ho gestito la mia discarica con il seguente sullo schiavo:

mysqldump -uROOTUSER -pROOTPASSWORD -hMYSQLMASTER.EXAMPLE.COM --all-databases --delete-master-logs | mysql -uROOTUSER -pROOTPASSWORD

Spero che questo aiuti qualcun'altro.

http://dev.mysql.com/doc/refman/5.0/en/reset-master.html

http://dev.mysql.com/doc/refman/5.0/en/reset-slave.html


modificato per includere FLUSH PRIVILEGES; Mi sono reso conto dopo un altro errore che anche se i miei utenti erano stati importati con il dump, i loro privilegi non erano ancora attivi.
BroknDodge

RESET MASTER dovrebbe essere eseguito sullo slave, non sul master, vedere percona.com/blog/2013/02/08/…
Jon

1

Se non si desidera REDO la procedura completa, una buona soluzione sarebbe usare

STOP SLAVE;    
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;

Se ci sono troppi di questi errori, una buona idea sarebbe quella di automatizzarlo usando uno script bash.

Rif: correzione dell'errore di inserimento duplicato


1

Ho avuto il problema esatto e il link di Ut xd mi ha aiutato. ma il comando in quel link aveva un errore di sintassi ed ecco la versione che ha funzionato per me:

while [ 1 ]; do if [ `mysql -uroot -ppassword -e"show slave status \G;" | grep "Duplicate entry" | wc -l` -eq 2 ] ; then mysql -uroot -ppassword -e"stop slave; set global sql_slave_skip_counter=1; start slave;"; fi; sleep 1; mysql -uroot -ppassword -e"show slave status\G"; done

In pratica controlla se c'è un errore di immissione duplicato e salta questo evento dal master. e farlo in un ciclo.


1
Questa sarebbe una risposta molto migliore se spiegassi cosa fa quel codice e formattassi il codice per renderlo più leggibile.
Kasperd,

0

Nel mio caso il problema è risolto dai seguenti comandi

con i seguenti passaggi

STOP SLAVE;
RESET SLAVE;
START SLAVE;
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.