MariaDB : résoudre l’erreur 1062 (duplicate entry for key PRIMARY) lors de la réplication des bases de données

Si vous utilisez les fonctions de réplication de MySQL ou MariaDB, il peut arriver que votre slave bloque sur une instruction qui devrait avoir un identifiant unique mais que le serveur tente d’insérer deux fois.

Et quand c’est le cas, la réplication des données prend fin donc c’est un problème à corriger rapidement si vous voulez que votre système haute disponibilité perdure et soit vraiment efficace en cas de coup dur.

Identification du problème

Je me suis rendu compte du problème lorsque j’ai ajouté de nouvelles bases à répliquer : j’ai relancé la procédure d’installation, relancé les serveurs, ajouté les nouvelles positions, démarré les slaves.

On regarde le status du slave :

MariaDB [(none)]> SHOW SLAVE STATUS\GLangage du code : CSS (css)

Résultat :

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.134.23.164
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mariadb-bin.000210
          Read_Master_Log_Pos: 2753885
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 103794
        Relay_Master_Log_File: mariadb-bin.000210
             Slave_IO_Running: Yes
            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: 1062
                   Last_Error: Error 'Duplicate entry '56-724' for key 'PRIMARY'' on query. Default database: 'frenchy'. Query: 'INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (56, 724)'
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1563407
              Relay_Log_Space: 1296874
              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: 1062
               Last_SQL_Error: Error 'Duplicate entry '56-724' for key 'PRIMARY'' on query. Default database: 'frenchy'. Query: 'INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (56, 724)'
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
               Master_SSL_Crl:
           Master_SSL_Crlpath:
                   Using_Gtid: No
                  Gtid_IO_Pos:
      Replicate_Do_Domain_Ids:
  Replicate_Ignore_Domain_Ids:
                Parallel_Mode: conservative
1 row in set (0.00 sec)Langage du code : JavaScript (javascript)

Comme on peut le constater, plusieurs choses ne tournent pas rond et empêchent la synchronisation des données entre nos deux serveurs :

Slave_SQL_Running: No
Last_SQL_Errno: 1062
Last_SQL_Error: Error 'Duplicate entry '56-724' for key 'PRIMARY'' on query. Default database: 'frenchy'. Query: 'INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (56, 724)'Langage du code : JavaScript (javascript)

Solution : un RESET sur le slave

En me documentant sur le problème, j’ai lu pas mal de choses sur le net. Certains préfèrent cacher l’erreur, au risque de perdre des données. D’autres préfèrent tout effacer pour recommencer la réplication.

Aucune de ces « solutions » ne me conviennent donc nous allons procéder autrement. Comme l’erreur n’apparaît que sur le serveur BACKUP et non sur le serveur principal, c’est sur lui que nous travaillerons.

Sur le serveur BACKUP, dans MariaDB, on arrête notre slave :

MariaDB [(none)]> STOP SLAVE;
Query OK, 0 rows affected (0.01 sec)Langage du code : CSS (css)

On flush les privilèges et donc les utilisateurs connectés :

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)Langage du code : CSS (css)

On efface les fichiers logs de notre slave. C’est comme effacer une ardoise pour repartir sur des bases saines. Cela ne supprime aucune donnée – cf le manuel sur RESET :

MariaDB [(none)]> RESET SLAVE;
Query OK, 0 rows affected (0.00 sec)Langage du code : CSS (css)

Et on redémarre notre slave :

MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.00 sec)Langage du code : CSS (css)

On vérifie de nouveau le status de notre slave :

MariaDB [(none)]> SHOW SLAVE STATUS\GLangage du code : CSS (css)

Résultat :

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.134.23.164
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mariadb-bin.000196
          Read_Master_Log_Pos: 77900062
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 6318821
        Relay_Master_Log_File: mariadb-bin.000192
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              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: 6318531
              Relay_Log_Space: 344030331
              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: 833890
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
               Master_SSL_Crl:
           Master_SSL_Crlpath:
                   Using_Gtid: No
                  Gtid_IO_Pos:
      Replicate_Do_Domain_Ids:
  Replicate_Ignore_Domain_Ids:
                Parallel_Mode: conservative
1 row in set (0.00 sec)Langage du code : CSS (css)

Nous avons bien :

Slave_IO_Running: Yes
Slave_SQL_Running: YesLangage du code : HTTP (http)

Et voilà, plus d’erreur et une réplication active dans les deux sens.

Demandez à l'IA son opinion
Gravatar for Matt Biscay

Je suis Matt Biscay, développeur WordPress & WooCommerce certifié chez Codeable, administrateur système et enseignant.

J’aide les entreprises à créer, optimiser et fiabiliser leurs sites WordPress avec une approche technique propre : performance, sécurité, maintenance, développement sur mesure et résolution de problèmes complexes.

Sur Skyminds, je partage des tutoriels WordPress, WooCommerce, Linux et administration système, avec des solutions testées sur des cas réels et pensées pour durer.

Découvrez mes services WordPress et WooCommerce.

2 réflexions au sujet de “MariaDB : résoudre l’erreur 1062 (duplicate entry for key PRIMARY) lors de la réplication des bases de données”

Laisser un commentaire