Il contatore dell'incremento automatico viene archiviato solo nella memoria principale, non sul disco.
http://dev.mysql.com/doc/refman/4.1/en/innodb-auto-increment-handling.html
Per questo motivo quando si riavvia il servizio (o server) si verificherà quanto segue:
Dopo l'avvio del server, per il primo inserimento in una tabella t, InnoDB esegue l'equivalente di questa istruzione: SELECT MAX (ai_col) FROM t FOR UPDATE;
InnoDB incrementa di uno il valore recuperato dall'istruzione e lo assegna alla colonna e al contatore di incremento automatico per la tabella. Se la tabella è vuota, InnoDB utilizza il valore 1.
Quindi, in parole povere, dopo l'avvio del servizio MySQL non ha idea di quale dovrebbe essere il valore di incremento automatico della tabella. Pertanto, quando si inserisce per la prima volta una riga, trova il valore massimo del campo che utilizza l'incremento automatico, aggiunge 1 a questo valore e utilizza il valore risultante. Se non ci sono righe, inizierà da 1.
Questo è stato un problema per noi, poiché utilizzavamo la tabella e la funzione di incremento automatico di mysql per gestire ordinatamente gli ID in un ambiente multi-thread in cui gli utenti venivano reindirizzati a un sito di pagamento di terze parti. Quindi abbiamo dovuto assicurarci che l'ID che la terza parte ci ha inviato e rispedito fosse univoco e che rimanesse tale (e ovviamente c'è la possibilità che l'utente annulli la transazione dopo essere stato reindirizzato).
Quindi stavamo creando una riga, ottenendo il valore di incremento automatico generato, eliminando la riga per mantenere pulita la tabella e inoltrando il valore al sito di pagamento. Quello che abbiamo finito per risolvere il problema del modo in cui InnoDB gestisce i valori di AI è stato il seguente:
$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);
Ciò mantiene sempre l'ultima transazioneId generata come riga nella tabella, senza far esplodere inutilmente la tabella.
Spero che possa aiutare chiunque altro a imbattersi in questo.
Modifica (18-04-2018) :
Come indicato di seguito da Finesse, il comportamento di questo è stato modificato in MySQL 8.0+.
https://dev.mysql.com/worklog/task/?id=6204
La formulazione in quel registro di lavoro è nella migliore delle ipotesi difettosa, tuttavia sembra che InnoDB in quelle versioni più recenti ora supporti valori di autoinc persistenti nei riavvii.
-Gremio