Qu'est-ce qui cause l'erreur MySQL 1062 - entrée en double lors du démarrage de l'esclave?

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

L'instantané du maître est créé par:

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

Ce fichier de vidage est importé sur l'esclave (qui est démarré avec --skip-slave-startoption) sans erreur:

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

Mais j'ai eu l'erreur suivante lors de l'exécution de 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, ...

Il n'y a qu'un seul enregistrement avec l'ID 115846 sur le maître:

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

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

Essayez d'ignorer certaines requêtes avec:

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

n'a pas aidé. Je ne veux pas ignorer ces erreurs en ajoutant:

slave-skip-errors = 1062

à my.cnfdéposer car cela peut rendre l'esclave incohérent.

Quelle peut être la raison de cette erreur?


MISE À JOUR

Ce n'est pas comme ça que je configure la réplication mySQL

Quelles étapes pensez-vous que je ne respecte pas le document?

Je me demande si vous rencontrerez le même problème si vous deviez installer la configuration entière plutôt qu'en passant la commande mysqldump.

Non, cela fonctionne normalement si je change également le maître en coordonnées correspondantes.

Je voudrais essayer de supprimer la base de données sur l'esclave, m'assurer que les binlogs sont clairs et recommencer. Vérifiez également le tableau en question sur le maître pour vous assurer que les index ne contiennent pas d'erreurs.

La suppression (déplacement) de toutes les données est-elle suffisante? Je l'ai fait et j'ai obtenu le même résultat.


Répondre à @Dmytro Leonenko

'afficher le statut de l'esclave \ G' sur l'esclave pour s'assurer qu'il est correctement configuré, MASTER_LOG_POS est 0

Uniquement "afficher l'esclave statug \ G" après l'importation mais avant "démarrer l'esclave;" peut nous donner la réponse

J'ai sauvegardé le datadir, tout supprimer et exécuter mysql_install_db, importer le fichier de vidage, exécuter change master toet voici les résultats:

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)

Je me demande pourquoi Master_Log_Pos a 4 ans?

quanta
la source
1
Il ne peut y avoir qu'un seul enregistrement avec cet identifiant, d'où l'erreur, il ne sera jamais écrit. Lorsque vous SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1émettez La requête à l'origine de l'erreur change-t-elle le moins? La position du journal des esclaves était-elle correctement configurée?
Thinice
Chaque fois que je saute le compteur, il passe à un autre ID. L' --master-dataoption est déjà d'écrire les coordonnées du journal binaire dans le fichier de vidage. J'ai seulement besoin de changer master en master_host, master_user, master_password.
quanta
Ce n'est pas ainsi que je configure habituellement la réplication mySQL (je configure généralement la réplication par URL ici: dev.mysql.com/doc/refman/5.0/en/replication-howto.html ) Cependant, en lisant les options de mysqldump, il n'y a aucune raison pourquoi cela ne devrait pas fonctionner. Je me demande si vous rencontrerez le même problème si vous deviez installer la configuration entière plutôt qu'en passant la commande mysqldump.
Rilindo
Voulez-vous dire que je ne devrais pas utiliser l' --master-dataoption lors de la création d'un instantané de données? Si cela se produit toujours lorsque j'utilise l' --lock-all-tablesoption et change master to master_log_file='', master_log_pos='', ..., quelles peuvent être les causes?
quanta
Non, ce n'est pas ce que je dis. Comme je l'ai mentionné, ce que vous avez fait devrait fonctionner comme prévu - pour autant que je sache, il n'y a pas de bogue existant avec cette option. Cependant, cela ne signifie pas qu'il n'y en a pas, donc comme étape d'isolement, je suivrais la convention fournie par mySQL d'abord via cette URL. t. Si cela fonctionne, vous avez au moins la direction pour commencer le dépannage. Si ce n'est pas le cas, eh bien, nous avons un problème différent. :)
Rilindo

Réponses:

7

Que tenter de résoudre votre problème:

  1. Vous devez d'abord supprimer master.info sur slave et redémarrer mysql
  2. émettez CHANGE MASTER TO MASTER_HOST = 'XX.XX.XX.XX', MASTER_USER = 'repl', MASTER_PASSWORD = 'slavepass';
  3. faire mysqldump avec l'option '--flush-logs' sur le maître
  4. 'mysql -u user -p <dump.sql' sur l'esclave
  5. 'afficher le statut de l'esclave \ G' sur l'esclave pour s'assurer qu'il est correctement configuré, MASTER_LOG_POS est 0
  6. 'start slave;' sur l'esclave.

À vérifier également:

  • Format binlog: MIXTE
  • server_ids sont différents sur maître et esclave
Dmytro Leonenko
la source
L'émission de toute la chaîne principale de changement (y compris le nom du journal et le numéro de position) le corrige en fait, mais à ce stade, je pense que la question principale est de savoir pourquoi Quanta doit entrer à nouveau le nom du journal et le numéro de position alors qu'il est déjà dans le fichier de vidage.
Rilindo
Uniquement "afficher l'esclave statug \ G" après l'importation mais avant "démarrer l'esclave;" peut nous donner la réponse
Dmytro Leonenko
ajouté les informations demandées dans mon message d'origine.
quanta
Comment vous êtes-vous retrouvé avec "Master_Host: xxxx Master_User: xx" sans lancer "CHANGE MASTER ...". Ou vous ne l'avez tout simplement pas mentionné en réponse? Avez-vous vérifié le format binlog et quelle était la ligne de commande pour mysqldump?
Dmytro Leonenko
J'ai déjà mentionné que dans mon article " importez le fichier de vidage, exécutezchange master to ". J'utilise la journalisation MIXED. J'ai testé avec MySQL 5.0.77 (basé sur des instructions), cela provoque également cette erreur. Le mysqldump complet estmysqldump -u root -p --all-databases --master-data --flush-logs > alldb_$(date +%F).sql
quanta
2

Le problème est dû à la configuration du maître sur un serveur de production en cours d'exécution AVANT d'effectuer le vidage (pour autant que je sache). Il existe donc des requêtes écrites dans le master_log qui ont déjà été exécutées sur les données résidant sur l'esclave. Je n'ai jamais vu de solution sur le site ou la liste de diffusion mysql. J'ai donc trouvé la solution suivante qui a résolu mon problème.

sur l'esclave:

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

sur le maître:

mysql> RESET MASTER;

sur l'esclave:

mysql> RESET SLAVE;
mysql> START SLAVE;

en passant, j'ai exécuté mon vidage avec ce qui suit sur l'esclave:

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

J'espère que ça aidera quelqu'un d'autre.

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
la source
modifié pour inclure les PRIVILÈGES FLUSH; J'ai réalisé après une autre erreur que même si mes utilisateurs avaient été importés avec le vidage, leurs privilèges n'étaient pas encore actifs.
BroknDodge
RESET MASTER doit être exécuté sur l'esclave, pas sur le maître, voir percona.com/blog/2013/02/08/…
Jon
1

Si vous ne voulez pas REDO la procédure complète, une bonne solution serait d'utiliser

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

S'il y a trop d'erreurs de ce type, une bonne idée serait de les automatiser à l'aide d'un script bash.

Réf: Correction d'une erreur d'entrée en double

Ut xD
la source
1

J'ai eu le problème exact et le lien d'Ut xd a aidé. mais la commande dans ce lien avait une erreur de syntaxe et voici la version qui a fonctionné pour moi:

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

Il vérifie essentiellement s'il y a une erreur d'entrée en double et ignore cet événement du maître. et faites-le en boucle.

perlwle
la source
1
Ce serait une bien meilleure réponse si vous expliquez ce que fait ce code et formatez-le pour qu'il soit plus lisible.
kasperd
0

Dans mon cas, le problème est résolu par les commandes suivantes

par les étapes suivantes

STOP SLAVE;
RESET SLAVE;
START SLAVE;
Karthik
la source