lock in depth #TechLunch

lock in depth #TechLunch

2012/04/04(水) @ Livesense TechLunch
発表者:桂 大介

E60aa4f80303f3f386898546ddb3686a?s=128

Livesense Inc.

April 23, 2014
Tweet

Transcript

  1. lock in depth katsura@livesense.co.jp

  2. ACID • Atomicity トランザクションが「全て実行される」か「全く実行さ れない」ことを保証する • Consistency 整合性制約を満たす • Isolation

    トランザクション中の過程が他から隠蔽される • Durability トランザクションが完了したら結果は永続する
  3. • Exclusive lock and Shared lock • Read lock and

    Write lock • Two-Phase Locking • Optimistic lock and Pessimistic lock • Timestamp Lock • Table-level lock and Row-level lock • Multiple granularity locking • Intention lock • Next key lock • Gap lock Lock
  4. eXclusive and Shared lock • 排他/専有(X)ロックと共有(S)ロック • 共有ロック中は共有ロックのみ取得可 • 排他ロック中はどちらのロックも取得不可

    • 共有ロック=読み込みロック • 排他ロック=書き込みロック
  5. Two-phase locking(2PL) • ロックの取得と開放は2つのフェイズに分かれて いる • 取得の順番が違うとデッドロックが起こる • Expanding phase(Growing

    phase)  ロックが取得されていくフェイズ • Shrinking phase  ロックが開放されるフェイズ
  6. Pessimistic Lock • 悲観的ロック(悲観的並行制御) • トランザクション開始時に対象のロックを取得 • 取得出来ない場合は待つorエラー投げる • ロックを取得

    • 安心して更新
  7. Optimistic Lock • 楽観的ロック(楽観的並行制御) • トランザクション開始時のバージョン番号を取得 • ロックは特に取らない • トランザクション進める

    • トランザクション終了時に開始時から更新されて いるかをチェック • 変更されていたらエラー投げる(orリトライ)
  8. Optimistic Lock その2 • 実装はtimestampかバージョン番号 • ActiveSupportはlock_versionカラムを用意する と勝手にOptimistic Lockをかける •

    cf. ActiveRecord::Locking::Optimistic • http://api.rubyonrails. org/classes/ActiveRecord/Locking/Optimist ic.html
  9. Table-level lock • MyISAMでお馴染みテーブルロック • MEMORYもテーブルロック • 省メモリ、高速 • UPDATE,

    DELETEがないときは使える
  10. • 行ロック • ロックコンフリクトが少ない • InnoDB他メジャーなやつはだいたい行ロック • メモリを多く消費する • テーブル全体をロックするクエリが多いときはパ

    フォーマンスが低い Row-level lock
  11. Transaction Isolation Level • トランザクションが同時に実行されたときに、どれ くらい分離されるか(影響されないか) • ANSI/ISO SQL標準では4つ定められている •

    Serializable • Repeatable Read • Read Committed • Read Uncommitted
  12. Serializable • それぞれのトランザクションは逐次実行した場合 と同じ結果となる • 分離レベルは一番高い • 安全だが低性能

  13. Repeatable Read • 同じ行のデータはトランザクション内で変更され ない • 同じ検索条件で新しい行が出てくること (Phantom Read)がある •

    InnoDBのデフォルト分離レベル
  14. Read Committed • コミット済みのデータのみ読み取る • 一度読み込んだデータをもう一度読み込むと データの内容が変更または削除されていること (Non-Repeatable Read)がある •

    Phantom Readもある
  15. Read Uncommitted • コミットされてなくても読み込む(Dirty Read) • Phantom, Non-Repeatableもある

  16. トランザクション分離レベル Phantom Read Non- Repetable Read Dirty Read Serializable ×

    × × Repeatable Read ◦ × × Read Committed ◦ ◦ × Read Uncommitted ◦ ◦ ◦
  17. InnoDB • 分離レベルは全て対応 • デフォルトはREPEATABLE READ • 全ての接続を変更するときはmy.cnfで • SET

    SESSION TRANSACTION ISOLATION LEVEL [LEVEL] でセッションのみも変更可 • SELECT @@tx_isolation; で確認
  18. mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ

    | +-----------------+ 1 row in set (0.03 sec)
  19. InnoDB Locks • Record Lock インデックスレコードのロック • Gap Lock インデックス間、最初のインデックスの前、最後のイ

    ンデックスの後ろのギャップのロック • Next Key Lock インデックスとインデックスの前のギャップの組み合 わせ
  20. Next Key Lock DEMO

  21. LOCK IN SHARE MODE FOR UPDATE • SELECTと同時にロックを取得 • LOCK

    IN SHARE MODE は共有 • FOR UPDATEは排他
  22. FOR UPDATE使わないと... 1. AがBEGIN, SELECT 2. BがBEGIN, UPDATE, COMMIT 3.

    AがUPDATE, COMMIT REPEATABLE READだとAが読むデータは3でも 変わらないが、実際データは変更されている。 →1のSELECTをFOR UPDATEにすることで2でロッ ク待ちになる SERIALIZABLEだと常にSELECTがLOCK IN SHARE MODE
  23. MVCC • MultiVersion Concurrency Control • 複数バージョンの同時並行性制御

  24. User A User B SET AUTOCOMMIT=0; SET AUTOCOMMIT=0; time |

    SELECT * FROM t; | empty set | INSERT INTO t VALUES (1, 2); | v SELECT * FROM t; empty set COMMIT; SELECT * FROM t; empty set COMMIT; SELECT * FROM t; --------------------- | 1 | 2 | --------------------- 1 row in set
  25. 次回は... 決戦!モナド