MySQL-Replikation: 'Doppelter Eintrag für PRIMARY-Schlüssel'

9

Könnten Sie mir bitte helfen, zu verstehen, warum ich nach einer vollständigen Neusynchronisierung auf einem Slave-Server "Doppelter Eintrag für PRIMARY-Schlüssel" erhalte?

Grundsätzlich lief 'mysqldump' fast die ganze Nacht und dann dauerte der Wiederherstellungsprozess ein paar Stunden. Als ich den Slave gestartet habe, waren es ~ 63874 Sekunden hinter dem Master.

Der Slave-Server ist schreibgeschützt (read_only) und während der erneuten Synchronisierung wurden keine Schreibvorgänge ausgeführt. Daher verstehe ich nicht, warum doppelte Schlüssel vorhanden sind.

Das Binärprotokollformat ist auf dem Master auf MIXED eingestellt.

Befehl zum Sichern der Datenbank:

mysqldump --opt --single-transaction -Q --master-data=2 db | bzip2 -cz > db.sql.bz2

Der Slave repliziert nur eine Datenbank vom Master (db -> db_backup) mit den folgenden Optionen:

replicate-wild-do-table = db_backup.%
replicate-rewrite-db = db->db_backup
HTF
quelle

Antworten:

11

ASPEKT 1: Replikation

Das glaube ich nicht

replicate-wild-do-table = db_backup.%
replicate-rewrite-db = db->db_backup

zusammen gehören.

Auch andere Leute haben sich darüber gewundert

Das Problem ergibt sich aus der Verarbeitung der Auftragsreplikationsregeln. Gemäß der MySQL-Dokumentation zu Replikationsregeln :

Wenn Optionen für --replicate-rewrite-db angegeben wurden, werden diese angewendet, bevor die Filterregeln für --replicate- * getestet werden.

Sogar die MySQL-Dokumentation zu replicate-rewrite-db sagt:

Die Übersetzung des Datenbanknamens erfolgt vor dem Testen der --replicate- * -Regeln.

Das replicate-wild-do-tablewird nach dem Umschreiben erzwungen. Es wäre nicht überraschend, wenn diese Reihenfolge ein INSERT in eine Tabelle einfügen würde, die bereits Daten enthält.

Sie fragen sich wahrscheinlich, wie die Daten dorthin gekommen sind?

ASPEKT 2: mysqldump

Dies mysqldump --single-transactionscheint der beste Weg zu sein, um Daten zu einem bestimmten Zeitpunkt zu speichern. Hat leider mysqldump --single-transactioneine Achillesferse : ALTER TABLE. Wenn eine Tabelle ALTER TABLEBefehlen wie einem DROP TABLEund unterliegt CREATE TABLE, die die Integrität der Transaktion beeinträchtigen können, hat der mysqldump versucht, den Speicherauszug auszuführen . Das Abschneiden einer Tabelle (im MySQL-Universum DDL) und das Löschen und Hinzufügen von Indizes können auch so störend sein.

Weitere Informationen hierzu finden Sie in MySQL Performance Blogs bestgehütetem MySQLDump Secret . Ich habe diesen Punkt in einer früheren Frage angesprochen, in der 12 Befehle beschrieben wurden, die die Integrität der Transaktion eines mysqldump beeinträchtigen können: MySQL backup InnoDB

VORBEHALT

EPILOG

Einer oder beide Aspekte haben möglicherweise dazu beigetragen, dass während des mysqldump eine Zeile eingefügt wurde, die aufgrund der Überschreibungsregeln oder der Isolierung des überschriebenen mysqldump nicht hätte existieren dürfen.

VORSCHLÄGE

Ich würde einen mysqlbinlog-Dump aller Relay-Protokolle seit dem Start des mysqldump durchführen, um alle INSERTs anzuzeigen, die der Slave verarbeiten wird, und um festzustellen, ob diese Zeilen bereits auf dem Slave vorhanden sind. Wenn ja, könnten Sie wahrscheinlich zwei Dinge tun:

1: Überspringen Sie alle Duplicate Key-Fehler

Fügen Sie dies einfach zu my.cnf auf dem Slave hinzu

[mysqld]
slave-skip-errors=1062
skip-slave-start

und starte mysql neu. Dann renneSTART SLAVE;

Alle doppelten Schlüsselfehler werden umgangen. Wenn Seconds_Behind_Master0 erreicht ist, entfernen Sie diese Zeilen und starten Sie mysql neu.

2: Laden Sie die Percona-Tools herunter

Die Werkzeuge, die Sie benötigen, sind

Verwenden Sie diese, um die Unterschiede im Slave zu finden und sie dann zu korrigieren

RolandoMySQLDBA
quelle
0

Überprüfen Sie, ob im Code eine Abfrage eingefügt wurde, die direkt in den Slave eingefügt wird. Wir können nur vom Sklaven lesen. Schreibabfragen sollten an den Master gerichtet werden.

Umair Anwar
quelle
Schau zurück auf die Frage. Der Slave ist schreibgeschützt und während der erneuten Synchronisierung werden keine Schreibvorgänge ausgeführt.
RolandoMySQLDBA