Was verursacht den MySQL-Fehler 1062 - doppelter Eintrag beim Starten des Slaves?

11
  • MySQL Master-Version: 5.5.16-1
  • MySQL Slave-Version: 5.5.18-1

Der Snapshot des Masters wird erstellt von:

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

Diese Dump-Datei wird auf den Slave importiert (mit dem gestartet wird --skip-slave-start ohne Fehler Option ):

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

Aber ich habe den folgenden Fehler beim Ausführen des 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, ...

Es gibt nur einen Datensatz mit der ID 115846 auf dem Master:

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

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

Versuchen Sie, einige Abfragen zu überspringen mit:

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

hat nicht geholfen. Ich möchte diese Fehler nicht überspringen, indem ich Folgendes hinzufüge:

slave-skip-errors = 1062

zu my.cnfarchivieren, weil es Slave inkonsistent bringen kann.

Was kann der Grund für diesen Fehler sein?


AKTUALISIEREN

So richte ich normalerweise die mySQL-Replikation nicht ein

Welche Schritte, von denen Sie glauben, dass ich dem Dokument nicht folge?

Ich frage mich, ob Sie auf dasselbe Problem stoßen werden, wenn Sie die gesamte Konfiguration einrichten und nicht den Befehl mysqldump übergeben.

Nein, es funktioniert wie gewohnt, wenn ich auch den Master auf entsprechende Koordinaten ändere.

Ich würde versuchen, die Datenbank auf dem Slave abzulegen, sicherzustellen, dass die Binlogs klar sind, und erneut starten. Überprüfen Sie auch die betreffende Tabelle auf dem Master, um sicherzustellen, dass die Indizes keine Fehler aufweisen.

Reicht das Löschen (Verschieben) des gesamten Datenverzeichnisses aus? Ich habe das getan und das gleiche Ergebnis erzielt.


Antwort an @Dmytro Leonenko

MASTER_LOG_POS ist 0, um sicherzustellen, dass es richtig konfiguriert ist

Nur 'Slave Statug \ G' nach dem Import anzeigen, aber vor 'Slave starten'; kann uns die Antwort geben

Ich habe den Datadir gesichert, alle gelöscht und ausgeführt mysql_install_db, die Dump-Datei importiert, ausgeführt change master tound hier sind die Ergebnisse:

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)

Ich frage mich, warum Master_Log_Pos 4 ist?

Quanten
quelle
1
Es kann nur einen Datensatz mit dieser ID geben, daher wird der Fehler niemals geschrieben. Bei der Ausgabe SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1Ändert sich die Abfrage, die den Fehler verursacht, im geringsten? Wurde die Position des Slave-Binlog korrekt eingerichtet?
Thinice
Jedes Mal, wenn ich den Zähler überspringe, ändert er sich in eine andere ID. Die --master-dataOption besteht bereits darin, die binären Protokollkoordinaten in die Speicherauszugsdatei zu schreiben. Ich muss nur master in master_host, master_user, master_password ändern.
Quanten
So richte ich normalerweise die mySQL-Replikation nicht ein (im Allgemeinen richte ich die Replikation per URL hier ein: dev.mysql.com/doc/refman/5.0/en/replication-howto.html ). Beim Lesen der mysqldump-Optionen gibt es jedoch keinen Grund warum sollte es nicht funktionieren. Ich frage mich, ob Sie auf dasselbe Problem stoßen werden, wenn Sie die gesamte Konfiguration einrichten und nicht den Befehl mysqldump übergeben.
Rilindo
Meinen Sie damit, dass ich die --master-dataOption beim Erstellen eines Datenschnappschusses nicht verwenden sollte ? Wenn es immer noch passiert, wenn ich die --lock-all-tablesOption verwende und change master to master_log_file='', master_log_pos='', ...was kann die Ursache dafür sein?
Quanten
Nein, das sage ich nicht. Wie ich bereits angedeutet habe, sollte das, was Sie getan haben, wie beabsichtigt funktionieren - soweit ich sehen kann, gibt es bei dieser Option keinen Fehler. Dies bedeutet jedoch nicht, dass dies nicht der Fall ist. Als Isolationsschritt würde ich daher zuerst die von mySQL über diese URL bereitgestellte Konvention befolgen. t. Wenn dies funktioniert, haben Sie zumindest die Anweisung, mit der Fehlerbehebung zu beginnen. Wenn das nicht so ist, haben wir ein anderes Problem. :)
Rilindo

Antworten:

7

Was Sie versuchen sollten, um Ihr Problem zu beheben:

  1. Sie sollten zuerst master.info auf dem Slave entfernen und mysql neu starten
  2. Geben Sie CHANGE MASTER TO MASTER_HOST = 'XX.XX.XX.XX', MASTER_USER = 'repl', MASTER_PASSWORD = 'Slavepass' aus.
  3. mache mysqldump mit der Option '--flush-logs' auf dem Master
  4. 'mysql -u user -p <dump.sql' auf dem Slave
  5. MASTER_LOG_POS ist 0, um sicherzustellen, dass es richtig konfiguriert ist
  6. 'Sklave starten;' auf Sklave.

Was auch zu überprüfen ist:

  • Binlog-Format: GEMISCHT
  • server_ids unterscheiden sich bei Master und Slave
Dmytro Leonenko
quelle
Das Ausgeben der gesamten Änderungsmasterzeichenfolge (einschließlich des Protokollnamens und der Positionsnummer) behebt das Problem tatsächlich, aber an diesem Punkt denke ich, dass die Kernfrage ist, warum Quanta den Protokollnamen und die Positionsnummer erneut eingeben muss, wenn dies bereits in der ist Dump-Datei.
Rilindo
Nur 'Slave Statug \ G' nach dem Import anzeigen, aber vor 'Slave starten'; kann uns die Antwort geben
Dmytro Leonenko
hat die angeforderten Informationen in meinen ursprünglichen Beitrag eingefügt.
Quanten
Wie sind Sie zu "Master_Host: xxxx Master_User: xx" gekommen, ohne "CHANGE MASTER ..." ausgegeben zu haben? Oder hast du es einfach nicht als Antwort erwähnt? Haben Sie das Binlog-Format überprüft und wie lautete die Befehlszeile für mysqldump?
Dmytro Leonenko
Ich habe bereits in meinem Beitrag " Dump-Datei importieren, ausführenchange master to " erwähnt. Ich verwende MIXED-basierte Protokollierung. Ich habe mit MySQL 5.0.77 (anweisungsbasiert) getestet, es verursacht auch diesen Fehler. Der volle mysqldump istmysqldump -u root -p --all-databases --master-data --flush-logs > alldb_$(date +%F).sql
Quanten
2

Das Problem wird dadurch verursacht, dass der Master auf einem laufenden Produktionsserver eingerichtet wird, bevor der Speicherauszug ausgeführt wird (soweit ich das beurteilen kann). Es gibt also Abfragen im master_log, die bereits für die Daten ausgeführt wurden, die sich auf dem Slave befinden. Ich habe auf der MySQL-Website oder in der Mailingliste nie eine Lösung gesehen. Also habe ich die folgende Lösung gefunden, die mein Problem gelöst hat.

auf Sklave:

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

auf Meister:

mysql> RESET MASTER;

auf Sklave:

mysql> RESET SLAVE;
mysql> START SLAVE;

Übrigens habe ich meinen Dump mit folgendem auf dem Slave ausgeführt:

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

Ich hoffe das hilft jemand anderem.

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

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

BroknDodge
quelle
bearbeitet, um FLUSH PRIVILEGES einzuschließen; Nach einem weiteren Fehler wurde mir klar, dass selbst wenn meine Benutzer mit dem Dump importiert wurden, ihre Berechtigungen noch nicht aktiv waren.
BroknDodge
RESET MASTER sollte auf dem Slave ausgeführt werden, nicht auf dem Master, siehe percona.com/blog/2013/02/08/…
Jon
1

Wenn Sie nicht möchten, dass REDO das gesamte Verfahren wiederholt, ist eine gute Lösung die Verwendung

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

Wenn es zu viele solcher Fehler gibt, ist es eine gute Idee, sie mithilfe eines Bash-Skripts zu automatisieren.

Ref: Fehler bei doppelter Eingabe behoben

Ut xD
quelle
1

Ich hatte das genaue Problem und der Link von Ut xd half. Aber der Befehl in diesem Link hatte einen Syntaxfehler und hier ist die Version, die für mich funktioniert hat:

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

Grundsätzlich wird geprüft, ob ein doppelter Eingabefehler vorliegt, und dieses Ereignis wird vom Master übersprungen. und mach es in einer Schleife.

perlwle
quelle
1
Dies wäre eine viel bessere Antwort, wenn Sie erklären würden, was dieser Code tut, und den Code so formatieren würden, dass er besser lesbar ist.
Kasperd
0

In meinem Fall wird das Problem durch die folgenden Befehle behoben

durch die folgenden Schritte

STOP SLAVE;
RESET SLAVE;
START SLAVE;
Karthik
quelle