ロックの基本

ロックってなんだ

データの整合性を保つために読み書きを一時的に制限する仕組み

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を同時に実行できるので追加と参照しかないならテーブルロック

ロックに関する問題

参考

  • このエントリーをはてなブックマークに追加
Feedforce Developer Blog

新しいブログへ移行しました!こちらもよろしくお願いします。