web-dev-qa-db-fra.com

Erreur d'entrée dupliquée MySQL 1062 lors de la restauration de la sauvegarde

Désolé, j'ai vu des threades similaires, mais je ne pouvais toujours pas le trouver aborder mon problème plus, j'avais besoin d'une autre information à ce sujet.

Exigence : Pour créer une réplique exacte 'DB4' d'un DB existant 'db3'.

Procédure suivie :

  • mysqldump -uuser -passer -pass DB3> dB3.sql (taille est 6G)
  • mySQL -UUUSER -PPASS DB4 <DB3.SQL (DB4 était une base de données vierge nouvelle créée)

La 2ème étape dans l'erreur:

ERROR 1062 (23000) at line 5524: Duplicate entry '600806' for key 1"

J'ai couru la 2ème étape avec --force. La restauration complétée mais avec 2 autres erreurs similaires:

ERROR 1062 (23000) at line 6309: Duplicate entry '187694' for key 1    
ERROR 1062 (23000) at line 6572: Duplicate entry '1567400' for key 1

À la fin lorsque j'ai interrogé certaines tables de base de données DB4, j'ai pu voir les enregistrements manquants.

Question :

  1. Cela indique-t-il une base de données DB3 corrompue/problématique?

  2. Comment procéder pour créer une réplique "cohérente/travail" (DB4) de DB3?

  3. Si (2) échoue, comment résoudre ce problème et trouver la raison derrière la raison pour laquelle cela se produit?

Merci,

4
user492160

Je suggérerais que cela indique effectivement un problème avec db3. Par défaut, MySqldump génère des relevés d'insertion "étendue", contenant plus d'une ligne d'insertion par ligne.

INSERT INTO table_name VALUES (...), (...), (...), ...;

Ceci est une optimisation, car plusieurs inserts dans une seule instruction sont beaucoup plus rapides que d'exécuter des déclarations d'insertion individuelles.

Mais vous pouvez désactiver ce comportement en utilisant le --skip-extended-insert option.

L'utilisation de cette option pour les sauvegardes n'est pas une bonne idée, puisqu'elle restaure beaucoup plus lentement, mais cette option permet de lire beaucoup plus facilement avec vos yeux et beaucoup plus facile à rechercher pour un enregistrement spécifique à l'aide de grep ou un outil similaire.

Dump la base de données à l'aide de cette option, puis recherchez dans le fichier pour les touches en double qui lance des erreurs et il semble probable que vous trouverez des lignes ou des lignes en double avec des touches en double qui auraient dû être unique ... ce qui signifie que la table sous-jacente db3.

Je ne peux pas penser à une façon que cela puisse arriver avec InnoDB mais avec MyISAM c'est nettement possible.

Il y a quelques autres options mysqldump pouvant également être utiles:

  • --replace génère un fichier écriture des déclarations comme REPLACE INTO à la place de INSERT INTO qui aboutirait aux enregistrements de clé en double survenant plus loin dans le fichier remplaçant les enregistrements contradictoires survenus plus tôt dans le fichier, sans générer une erreur
  • --insert-ignore génère un fichier avec les déclarations écrites comme INSERT IGNORE INTO à la place de INSERT INTO, qui entraînerait une persistance des enregistrements de clé en double avant dans le fichier dans les tableaux restaurés, car les enregistrements conflictuels ultérieurs seraient ignorés, non insérés et ne généreraient pas une erreur.
6
Michael - sqlbot

On peut même rechercher et remplacer chaque occurrence de Insert dans avec INSERT IGNORE IN dans le fichier MySQLDUMP.

4
Sachin Singh

Préface

J'ai donc rencontré cette question après que l'un de nos serveurs de réplication soit entré dans un état incohérent. Nous ne pouvions pas le remettre en ligne avec une solution rapide et avons décidé de réinitialiser la réplication avec une nouvelle sauvegarde.

La question indiquée ci-dessus n'est pas le même problème, mais renvoie la même erreur que j'ai donc décidé d'ajouter cette réponse au cas où d'autres personnes la recherchent.

C'est aussi un duplicata exact de cette question sur faute de serveur mais parce que cette question a un classement plus élevé dans (mes) résultats de Google, je l'ai également posté là-bas.

Qu'est-ce que nous avons fait

Nous avons supprimé toutes nos bases de données sur l'instance avec MySQL Workbench, j'ai redémarré l'instance et vérifié la vérité sur laquelle aucune base de données n'est laissée dans l'instance. Sur le serveur maître, nous avions déjà commencé à créer une nouvelle sauvegarde avec le script que nous utilisons toujours.

Ensuite, une fois la sauvegarde sur le serveur défaillant, nous avons démarré l'importation et, après quelques heures, elle avait importé la plupart des données et a échoué avec ce type d'erreurs:

ERROR 1062 (23000) at line XXX: Duplicate entry 'dbName-tblName' for key 'PRIMARY'
Operation failed with exitcode 1

Nous avons pensé d'accord, peut-être que quelque chose s'est mal passé lors de la création de la sauvegarde, j'ai vérifié les données dans la sauvegarde mais que vous ne trouvez rien de mal. Nous avons de nouveau réessayé toutes les étapes juste pour être sûr de ne rien manquer d'autre que malheureusement, il n'y avait pas de cigare ..

le problème réel

L'erreur affichée n'est pas l'insertion réelle des données mais la création d'un index. C'est pourquoi les données ont été insérées sans problème (nous avons vérifié) mais ont toujours généré une erreur. La suppression apparemment toutes les tables n'est pas suffisante, les données d'index existe toujours sur le serveur (cela peut être dû à une modification de MySQL 5.6, car nous n'avions jamais eu ce problème auparavant). Et comme l'importation de ces index est quelque part au milieu du fichier d'importation, le reste des données n'a pas été importée.

le correctif

Nous avons supprimé le fichier ibdata1 et tous les fichiers Innodb_index_Stats et Innodb_Table_Stats dans le dossier de base de données MySQL, puis ont commencé l'instance. MySQL vous dira ensuite que certaines tables système sont manquantes vous pouvez trouver plus d'informations sur cela ici

Cela a résolu notre problème et notre serveur se réplique désormais comme prévu.

Espérons que cela sauver quelques heures pour quelqu'un quelque part :)

1
Sc0tTy