自動インクリメントカウンタは、ディスクではなくメインメモリにのみ保存されます。
http://dev.mysql.com/doc/refman/4.1/en/innodb-auto-increment-handling.html
このため、サービス(またはサーバー)が再起動すると、次のことが起こります。
サーバーの起動後、テーブルtへの最初の挿入に対して、InnoDBは次のステートメントに相当するものを実行します。SELECT MAX(ai_col)FROM t FOR UPDATE;
InnoDBは、ステートメントによって取得された値を1増分し、それを列およびテーブルの自動増分カウンターに割り当てます。テーブルが空の場合、InnoDBは値1を使用します。
したがって、簡単な英語では、MySQLサービスの開始後、テーブルの自動インクリメント値がどうあるべきかがわかりません。したがって、最初に行を挿入すると、自動インクリメントを使用するフィールドの最大値が検出され、この値に1が加算されて、結果の値が使用されます。行がない場合は、1から始まります。
ユーザーがサードパーティの支払いサイトにリダイレクトされるマルチスレッド環境で、テーブルとmysqlの自動インクリメント機能を使用してIDをきちんと管理していたため、これは私たちにとって問題でした。そのため、サードパーティが取得して返送したIDが一意であり、そのままであるようにする必要がありました(もちろん、ユーザーがリダイレクト後にトランザクションをキャンセルする可能性があります)。
そこで、行を作成し、生成された自動インクリメント値を取得し、行を削除してテーブルをクリーンに保ち、値を支払いサイトに転送していました。InnoDBがAI値を処理する方法の問題を修正するために私たちがやったことは次のとおりでした。
$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);
これにより、テーブルを不必要に爆破することなく、常にテーブル内の行として生成された最新のtransactionIdが保持されます。
これに遭遇する可能性のある他の誰にも役立つことを願っています。
編集(2018-04-18):
Finesseが以下で言及したように、この動作はMySQL 8.0以降で変更されているようです。
https://dev.mysql.com/worklog/task/?id=6204
そのワークログの文言はせいぜい不完全ですが、それらの新しいバージョンのInnoDBはリブート後も永続的なautoinc値をサポートするようになりました。
-グレミオ