もし InnoDB
テーブルに
AUTO_INCREMENT
カラムを指定すると、InnoDB
データ ディレクトリ内のテーブル
ハンドルは、カラムに新しい値を割り当てるのに利用される自動インクリメント
カウンタと呼ばれる特別なカウンタを含みます。このカウンタは、ディスク上には格納されず、主メモリ内だけに格納されます。
InnoDB
は、ai_col
を名づけた AUTO_INCREMENT
カラムを含むテーブル T
に自動インクリメント
カウンタを初期化する為に、次のアルゴリズムを利用します:サーバの起動の後で、テーブル
T
への最初の挿入をする為に、InnoDB
はこのステートメントと同等な物を実行します:
SELECT MAX(ai_col) FROM T FOR UPDATE;
InnoDB
はステートメントによって値が取り出された物によってインクリメントし、それをカラムとテーブルの自動インクリメント
カウンタに割り当てます。もしテーブルが空だったら、InnoDB
は値 1
を利用します。もしユーザがテーブル
T
の為のアウトプットを表示する
SHOW TABLE STATUS
ステートメントを呼び出し、自動インクリメント
カウンタがまだ初期化されていなかったら、InnoDB
は値を初期化するがインクリメントはせず、そしてそれを後で挿入に利用する為に格納します。この初期化はテーブル上で通常の専用ロック読み込みを利用し、そのロックはトランザクションの最後まで続くという事に注意してください。
InnoDB
は、作成されたばかりのテーブルの為に自動インクリメント
カウンタを初期化するのと同じ手順に従います。
自動インクリメント
カウンタが初期化された後、もしユーザが
AUTO_INCREMENT
カラムの値を明示的に指定しなければ、InnoDB
はカウンタを1でインクリメントしカラムに新しい値を割り当てます。もしユーザがカラム値を明示的に指定する行を挿入し、それが現在のカウンタ値よりも大きければ、カウンタは指定されたカラムに設定されます。
もしカウンタを利用して生成された数値を持つトランザクションをロールバックすると、AUTO_INCREMENT
に割り当てられた値のシーケンス内のギャップに気がつくでしょう。
もしユーザが NULL
か
0
を INSERT
内の
AUTO_INCREMENT
カラムに指定すると、InnoDB
は、値が指定されず、新しい値も生成されていないかのように行を扱います。
自動インクリメント構造の性能は、もしユーザがカラムにマイナスの値を割り当てたり、もし値が指定した整数タイプ内に格納する事ができる最大値を上回っていたりすると、定義できません。
自動インクリメント
カウンタにアクセスする時、InnoDB
は、トランザクションの最後までではなく、現在の
SQL
ステートメントの最後まで続く、特別なテーブル
レベル AUTO-INC
ロックを利用します。AUTO_INCREMENT
カラムを含んでいるテーブルへの挿入の並行処理を向上させる為に、特別ロック
リリース戦略が紹介されました。それにもかかわらず、2つのトランザクションは
AUTO-INC
ロックが長時間保持されればパフォーマンス
インパクトを与える事ができる
AUTO-INC
ロックを同じテーブル上で同時に持つ事ができません。
これは、1つのテーブルから全ての行を別のテーブルに挿入する
INSERT INTO t1 ... SELECT ... FROM t2
のようなステートメントのような場合の事です。
InnoDB
はサーバが起動している限り、メモリ内の自動インクリメント
カウンタを利用します。サーバが停止し再起動した時、先ほど説明があったように、InnoDB
は、テーブルへの最初の INSERT
に対する各テーブルのカウンタを再初期化します。
InnoDB
は、初期カウンタ値を設定したり、現在のカウンタ値を変更する為に、CREATE
TABLE
と ALTER TABLE
ステートメント内の AUTO_INCREMENT =
テーブル
オプションをサポートします。このセクションの最初の方で説明があったとおり、このオプションの効果はサーバの再起動によって無くなってしまいます。
N