2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ツリー構造から見るMySQLのインテンションロック

Last updated at Posted at 2023-07-23

ストレージエンジンは InnoDB. MySQL バージョンは 8.0.33

目次

  • 前置き - ロックの粒度
    • A. データベースロック
    • B. テーブルロック
    • C. ページロック
    • D. 行ロック
  • 本題 - インテンションロック
  • 想定外ロックを避けるには

前置き - ロックの粒度

( この辺知ってる、という方は 本題 - インテンションロック まで進んでください )

ロックの粒度は次の4つ

  • A. データベースロック
  • B. テーブルロック
  • C. ページロック
  • D. 行ロック

図にすると次の通り。

‎lock_intention.‎001.jpeg

A. データベースロック

MySQL では明示的にデータベースロックする「コマンド」や「設定値」はない。

以下 2 つでそれに近い状態が出来上がる。

疑似的なロック

FLUSH TABLES WITH READ LOCK;

この SQL は以下の特性を持つ。

  • テーブル全体に向けて
  • 書込を禁止する
  • 読取を許可する
UNLOCK TABLES;

で解除可能。

長く続くトランザクション

意図的でない限り、 一つのトランザクションが延々と続く場合は

他トランザクションをロックする可能性を高くする。

その意味で、データベースロックと似た状況が生じる。

  • 例1.) 何千万、何億とある SQL を一つのトランザクションで処理する
  • 例2.) インデックス設計が不適切で、何十分経っても結果を取得できない

B. テーブルロック

テーブル全体に対するロック

例えば、テーブル内の全行を一括更新・削除する場合に発生する。

参考ページ

C. ページロック

ここでは省略。

述語ロック(Predicate Lock)」がこれに対応するが、他のロックに比べれば発生頻度(利用頻度)は低いと思われるため。

補足:ページとは

データを保存・管理する基本単位のことで「コンテナ」がイメージとして近い。

以下 4 種類のデータを格納する。

  • テーブルの行データ
  • インデックスデータ
  • トランザクション情報
  • (ページそのものの)メタデータ

参考ページ

D. 行ロック

行に対するロック

ロックの範囲が行単位である。

参考ページ

本題 - インテンションロック

インテンションロックとは、

  • トランザクションがテーブルに対して取得するロックのこと
  • B. のテーブルロックとは別物

図解すると以下の通り

その1 - 最初にインテンションロックを確認する

  • トランザクションは、テーブルに「インテンションロック」があるか確認する

‎lock_intention.‎002.jpeg

その2 - テーブルにインテンションロック・行にロックを取得

確認の結果、テーブルにインテンションロックがないので

  • テーブルにインテンションロックを取得
  • 行にロックを取得
    • トランザクションが続く限り、上 2 つのロックは継続する

‎lock_intention.‎003.jpeg

その3 - 別トランザクションがインテンションロックを確認

別トランザクションが、テーブルのインテンションロックを確認する

  • 行ロック可能かを テーブルのインテンションロックから確認する
  • (できないので)先約のトランザクション完了待ち
    • いわゆるロック状態・ロック解放待ち

できる・できないの突合はドキュメントのマトリクスを参照

‎lock_intention.‎004.jpeg

その4 - トランザクション再開後、先にインテンションロックする

先約トランザクション完了 = ロック解放されたら、次のトランザクション用に

  • テーブルにインテンションロックを取得
  • 行にロックを取得

‎lock_intention.‎005.jpeg

なぜ、インテンションロックが必要か

処理効率化のため。

例えば、テーブル T1 の行数(レコード数) が 5,000万あると仮定する。

インテンションロックがない場合、インデックスが適切でない SQL 等は

「全行の検査」が必要。逐次処理では非常に無駄なため、

インテンションロックが設けられている。

想定外ロックを避けるには

  • 長いトランザクション
  • インテンションロック

が組み合わさると、予期しないロックが発生する。なので、次に留意したい

  • 特に理由がない限り、トランザクションは短くすること
    • 取得と更新のトランザクションは分けるなど
  • インデックス設計を見直して、高速化を図ること
  • 性能テスト・負荷テストをして以下を確認すること
    • 長いトランザクションが発生しないか
    • 競合しあうトランザクションは発生しないか

参考

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?