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\GCode language: 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)Code language: 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)'Code language: 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)Code language: 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)Code language: 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)Code language: CSS (css)

Et on redémarre notre slave :

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

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

MariaDB [(none)]> SHOW SLAVE STATUS\GCode language: 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)Code language: CSS (css)

Nous avons bien :

Slave_IO_Running: Yes
Slave_SQL_Running: YesCode language: HTTP (http)

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

Envie d'ajouter des fonctionnalités exceptionnelles à votre site WordPress ou WooCommerce? Je suis là pour vous aider.

Explorons les possibilités ensemble »

Matt

Matt Biscay est développeur WordPress et WooCommerce certifié chez Codeable, ainsi que sysadmin qualifié et enseignant-chercheur. Passionné par le code performant et les solutions sécurisées, je m'efforce d'offrir une expérience utilisateur exceptionnelle sur chaque projet.

Vous avez aimé cet article ? Vous avez un projet en tête et vous pensez que je pourrais vous aider à le concrétiser ? N'hésitez pas à me contacter, je serais ravi de discuter avec vous de votre projet !

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

Opinions