Le compteur d'incrémentation automatique est stocké uniquement dans la mémoire principale, pas sur le disque.
http://dev.mysql.com/doc/refman/4.1/en/innodb-auto-increment-handling.html
Pour cette raison, lorsque le service (ou le serveur) redémarre, les événements suivants se produisent:
Après un démarrage de serveur, pour la première insertion dans une table t, InnoDB exécute l'équivalent de cette instruction: SELECT MAX (ai_col) FROM t FOR UPDATE;
InnoDB incrémente de un la valeur récupérée par l'instruction et l'affecte à la colonne et au compteur d'incrémentation automatique de la table. Si la table est vide, InnoDB utilise la valeur 1.
Donc, en clair, après le démarrage du service MySQL, il n'a aucune idée de la valeur d'incrémentation automatique de votre table. Ainsi, lorsque vous insérez une ligne pour la première fois, elle trouve la valeur maximale du champ qui utilise l'incrémentation automatique, ajoute 1 à cette valeur et utilise la valeur résultante. S'il n'y a pas de lignes, il commencera à 1.
C'était un problème pour nous, car nous utilisions la table et la fonction d'incrémentation automatique de mysql pour gérer proprement les identifiants dans un environnement multithread où les utilisateurs étaient redirigés vers un site de paiement tiers. Nous avons donc dû nous assurer que l'ID que le tiers avait obtenu et renvoyé était unique et resterait ainsi (et bien sûr, il est possible que l'utilisateur annule la transaction après avoir été redirigé).
Nous avons donc créé une ligne, obtenu la valeur d'auto-incrémentation générée, supprimé la ligne pour garder la table propre et transmis la valeur au site de paiement. Ce que nous avons fini par faire pour résoudre le problème de la façon dont InnoDB gère les valeurs AI était le suivant:
$query = "INSERT INTO transactions_counter () VALUES ();";
mysql_query($query);
$transactionId = mysql_insert_id();
$previousId = $transactionId - 1;
$query = "DELETE FROM transactions_counter WHERE transactionId='$previousId';";
mysql_query($query);
Cela conserve toujours le dernier transactionId généré sous forme de ligne dans la table, sans faire exploser inutilement la table.
J'espère que cela aide toute autre personne qui pourrait rencontrer cela.
Modifier (18/04/2018) :
Comme Finesse l'a mentionné ci-dessous, il semble que son comportement ait été modifié dans MySQL 8.0+.
https://dev.mysql.com/worklog/task/?id=6204
Le libellé de ce journal de travail est au mieux défectueux, mais il semble qu'InnoDB dans ces versions plus récentes prend désormais en charge les valeurs autoinc persistantes à travers les redémarrages.
-Gremio