Réplication MySQL: 'Entrée dupliquée pour la clé PRIMAIRE'

9

Pourriez-vous, s'il vous plaît, m'aider à comprendre pourquoi je reçois "Entrée dupliquée pour la clé PRIMAIRE" sur un serveur esclave après une resynchronisation complète.

Fondamentalement, 'mysqldump' fonctionnait presque toute la nuit, puis le processus de restauration a pris quelques heures, donc quand j'ai démarré l'esclave, il était ~ 63874 secondes derrière le maître.

Le serveur esclave est en lecture seule (read_only) et il n'y a eu aucune écriture pendant le processus de resynchronisation, donc je ne comprends pas pourquoi il y a des clés dupliquées.

Le format du journal binaire est défini sur MIXTE sur le maître.

Commande utilisée pour sauvegarder la base de données:

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

L'esclave réplique une seule base de données du maître (db -> db_backup) avec les options suivantes:

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

Réponses:

11

ASPECT # 1: Réplication

Je ne pense pas que

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

aller ensemble.

D'autres personnes se sont également interrogées à ce sujet

Le problème provient des règles de réplication de commande qui sont traitées. Selon la documentation MySQL sur les règles de réplication :

Si des options --replicate-rewrite-db ont été spécifiées, elles sont appliquées avant que les règles de filtrage --replicate- * ne soient testées.

Même la documentation MySQL sur replicate-rewrite-db dit:

La traduction du nom de la base de données est effectuée avant que les règles --replicate- * ne soient testées.

Le replicate-wild-do-tableest appliqué après la réécriture. Il ne serait pas surprenant que cette commande impose en quelque sorte un INSERT dans une table qui contient déjà des données.

Vous vous demandez probablement comment les données y sont arrivées?

ASPECT # 2: mysqldump

Faire mysqldump --single-transactionsemblerait être le meilleur moyen de décharger des données à un moment précis. Malheureusement, mysqldump --single-transactiona un talon d'Achille: ALTER TABLE. Si une table est soumise à des ALTER TABLEcommandes, telles que a DROP TABLEet CREATE TABLE, qui peuvent briser l'intégrité de la transaction dans laquelle mysqldump tentait d'effectuer le vidage. Tronquer une table (qui est DDL dans l'univers MySQL) et supprimer et ajouter des index peut être aussi perturbateur.

Vous pouvez trouver plus d'informations à ce sujet dans le secret MySQLDump le mieux gardé de MySQL Performance Blog . J'ai en fait abordé ce point dans une question précédente décrivant 12 commandes qui peuvent briser l'intégrité d'une transaction mysqldump: MySQL backup InnoDB

CAVEAT

ÉPILOGUE

Un ou les deux aspects peuvent avoir contribué à laisser une ligne se glisser pendant le mysqldump qui n'aurait pas dû exister en raison des règles de réécriture ou de l'isolement du mysqldump qui a été remplacé.

SUGGESTIONS

Je ferais un vidage mysqlbinlog de tous les journaux de relais depuis le début du mysqldump pour voir tous les INSERT que l'esclave traitera et voir si ces lignes existent déjà sur l'esclave. S'ils le font, vous pourriez probablement faire deux choses:

1: Ignorez toutes les erreurs de clé en double

Ajoutez simplement ceci à my.cnf sur l'esclave

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

et redémarrez mysql. Ensuite, exécutezSTART SLAVE;

toutes les erreurs de clé en double seront contournées. Quand Seconds_Behind_Masterarrive à 0, supprimez ces lignes et redémarrez mysql.

2: Téléchargez les outils Percona

Les outils dont vous avez besoin sont

Utilisez-les pour trouver les différences dans l'esclave, puis corrigez-les

RolandoMySQLDBA
la source
0

Vérifiez la requête d'insertion dans le code qui s'insère directement dans l'esclave. Nous ne pouvons lire que depuis l'esclave. Les requêtes d'écriture doivent être dirigées vers master.

Umair Anwar
la source
Revenez à la question. L'esclave est en lecture seule et il n'y a aucune écriture pendant la resynchronisation.
RolandoMySQLDBA