エンジニアのはしがき

プログラミングの日々の知見を書き連ねているブログです

InnoDBのロックについてまとめた

MySQLを実務で触っているのですが、改めてInnoDBのロックの仕様について頭の整理をするためにまとめてみました。

ロックの種類

共有ロックと排他のロックの2種類があり、トランザクション分離レベルによって挙動が変わります。 InnoDBのデフォルトは"REPEATABLE READ"で、SELECT @@transaction_ISOLATIONで確認が可能です。

トランザクション分離レベルについては以下を参照。

MySQL :: MySQL 8.0 Reference Manual :: 15.7.2.1 Transaction Isolation Levels

なお以下の説明は"REPEATABLE READ"での挙動になります。

共有ロック

  • トランザクションからの読み取り(SELECT)を許可し、更新(INSERT, UPDATE, DELETE)は禁止します。
    • SELECTする際にFOR SHARE(MySQL 8.0.0以前の記法だとLOCK IN SHARE MODE)を付与すると共有ロックをかけられます。

排他ロック

  • トランザクションからの読み取り(SELECT)、更新(INSERT, UPDATE, DELETE)の双方を禁止します。
    • INSERT, UPDATE, DELETEする際に排他ロックがかかります。
    • ただ必ずしもすべてのSELECTが禁止されるわけではなく、通常のSELECT(non-locking read / consistent read)では読み取りは許可されます。

ロックの範囲

共有ロック、排他ロックが適用される範囲にはいくつか種類があります。

各ロックの相関関係や扱われ方については、自分で書くよりこちらのブログの説明が視覚的にも分かりやすいので紹介いたします。

レコードロック

  • 特定のレコードに対してのロック。

ギャップロック

  • インデックスの隙間に対してのロック。

ネクスキーロック

  • レコードロックとギャップロックを併用したロック。

テーブルロック

  • 対象のテーブル全体へのロック。

ロックの範囲はどのように決まるのか

  • インデックスが貼られている、またはUNIQUE制約のあるカラムを対象にした場合は「レコードロック」or「ギャップロック」or「ネクスキーロック
  • 上記以外は「テーブルロック」

参考

MySQL :: MySQL 8.0 Reference Manual :: 15.7.1 InnoDB Locking

MySQL|占有ロック(FOR UPDATE)と共有ロック(LOCK IN SHARE MODE) - わくわくBank

MySQL - InnoDBのロック関連まとめ - Qiita

良く分かるMySQL Innodbのギャップロック - Qiita

ネクストキーロックとは | ソフトウェア雑記

主要RDBMS製品の比較 – 同時実行制御, トランザクション分離レベル | コーソルDatabaseエンジニアのBlog