MyISAMのロック

MyISAMはテーブルロックだということは知っているけど、細かなところが怪しいので、調べてみた。

テーブルロック

読み出し時(SELECT)は読み出しロックを取得し、書き込み時(INSERT, UPDATE, DELETE, ALTER TABLE)は書き込みロックを取得する。

読み出しロック時の挙動

他のクライアントも読み出しロックを取得して、読み込みが可能。
書き込みロックは読み出しが終わるまで待機しないと取得できない。

書き込みロック時の挙動

他のクライアントは読み出し/書き込み、いずれのロックも取得できない。

コンカレントインサート

重いSELECT実行されるとロック解放されず、すべてが待たされてしまい大変!
ってことでMyISAMにはコンカレントインサートという機能があるらしい。

http://dev.mysql.com/doc/refman/5.1/ja/internal-locking.html

MyISAMテーブルが中心に空きブロックを持たない場合、行は必ずデータファイルの後部に挿入される。この場合、併発するINSERTおよびSELECTステートメントをロックなしでMyISAMテーブルに対して自由に混合して使用できます。つまり、他のクライアントが読むのと同時にMyISAM テーブルに行を挿入できます。テーブルの途中で行を更新もしくは削除した場合欠落が生じます。欠落がある場合、同時挿入はできませんが、全ての欠落が新しいデータで満たされた場合は、自動的に再使用可能となります。

http://dev.mysql.com/doc/refman/5.1/ja/concurrent-inserts.html

MyISAM テーブルでは、テーブルに削除された行がない場合、SELECTの実行と同時に行を挿入できる

ふむー。後ろに行追加するテーブルなら、コンカレントインサートできるってことだ(まんま)。
データを更新/削除するとフラグメンテーションが発生すると言い換えることもできる。

確認するためのコマンド。

show variables like 'concurrent_insert';
  • 1: 途中で欠落がない時だけ、コンカレントインサート(※デフォルト)
  • 2: 途中に欠落ある時にも、強制的にコンカレントインサート

フラグメンテーションを解消するコマンド(運用中にやっていいかどうかは知らない>_<)
http://dev.mysql.com/doc/refman/4.1/ja/optimize-table.html

optimize table [table_name];


まだまだ、知らないことがたくさんだ。