MySQL ロックの話
- 2006.10.06
- 勉強会資料
ロックの基本
ロックってなんだ
データの整合性を保つために読み書きを一時的に制限する仕組み
READロックとWRITEロック
READロック
- 共有ロック
- 他のスレッドによるデータの読み込みは可能
- 他のスレッドによるデータ変更は不可
WRITEロック
- 排他ロック
- 他のスレッドによる読み込みも変更も不可
ロックキューと優先順位
- ロック要求を出したときに対象がロック済みの場合はロックキューに要求を入れる
- WRITEロックキューとREADロックキューがあり、WRITEロックキューが優先的に処理される
- よってWRITEロックが続くとSELECTできない状態になる
- この優先順位はいろんな単位で変更可能
基本的に更新をなるべく早く反映させるためにWRITEロックが優先される
ロックレベル
テーブルロック
- ISAM/MyISAM/HEAP
- テーブル単位のロック
- デッドロックフリー
- 大部分が読み込みの場合に適する
ページロック
- DBD
- ページ(データ格納ブロックの最小単位)単位のロック
行ロック
- InnoDB
- 行(レコード)単位のロック
- 多くのスレッドが異なったレコードにアクセスする際にロックの競合が少ない
- ロールバックの変更が少ない
- 単一レコードを長時間ロックしても他のスレッドへの影響が最小限
- 他のロックに比べて多くのメモリを消費する
- 対象レコードが多い場合、多数のロックがかかるために遅くなる
- テーブルロック等に比べるとアプリケーション側に最適化の余地が少ない
ロックの活用
明示的なロック
- LOCK TABLES
UNLOCK TABLES
明示的にロックしない場合より速い
あるスレッドにおける複数のSQLで一貫した処理
UNLOCKされないでスレッドが終了した場合はLOCKは解除される
トランザクションの途中でLOCK TABLESするとそこでCOMMITが入る
MySQL 4.1 リファレンスマニュアル :: 6.7.5 LOCK TABLES および UNLOCK TABLES 構文
Priorityの指定
SELECT, INSERT, UPDATE, DELETE, REPLACE文で
- SELECT HIGH PRIORITY
- INSERT LOW PRIORITY
- UPDATE LOW PRIORITY
- DELETE LOW PRIORITY
- REPLACE LOW PRIORITY
SET文で
- SET LOW_PRIORITY_UPDATES = 0 | 1
起動オプションで
- --low-priority-updates
ロックレベルの選択
- 読み取りメインならテーブルロック
- 時間のかかるクエリがなければテーブルロック
- 更新頻発なら行ロック
- 時間のかかるクエリがあるなら行ロック
- MyISAMはSELECTとINSERTを同時に実行できるので追加と参照しかないならテーブルロック