Db2のロックとは?範囲や種類、ロックエスカレーションについて解説

Db2

はじめに

データベースでは、複数のユーザーやアプリケーションが同時にデータへアクセスします。

もし制御なしに更新が行われると、以下の問題が発生します。

  • 更新内容の上書き(ロストアップデート)
  • 読み取りの不整合(ダーティリード)
  • 処理結果の不一致

これを防ぐために、Db2ではロックによる排他制御を行います。


ロックの対象と範囲

ロックは以下の単位で取得されます。

対象説明
行(Row)最も細かい
表(Table)行単位制御が困難な場合
表スペースユーティリティなどで使用
  • 通常のSQL:行 or 表ロック
  • ユーティリティ:表スペースロックあり
  • 索引にはロックは取得されない

ロック範囲が広くなるほど、並列性低下、ロック競合増加につながります。


ロックの種類と互換性

ロックにはモード(種類)があり、他のロックと同時に取得できるか(互換性)が決まっています。

基本ロックの互換性

要求\保持S(共有)U(更新)X(排他)
S(共有)×
U(更新)××
X(排他)×××
  • ○:同時に取得可能
  • ×:待機(ロック待ち)

ポイント

  • S(共有):参照用(SELECT)
  • U(更新):更新前の中間ロック
  • X(排他):更新用(INSERT/UPDATE/DELETE)

つまり、

  • 読み取り同士は共存できる
  • 更新は基本的に単独

というシンプルなルールです。


ロックのモード詳細

Db2ではさらに細かいロックモードが存在します。

×の場合、ロック取得不可能であるためロック待ちとなります。

補足

  • アクセス経路や分離レベルにより取得ロックは変わる
  • 表ロック+行ロックの組み合わせで制御される

ロックの保持期間

Db2におけるロックは、トランザクション単位で保持されます。
つまり、ロックは COMMIT または ROLLBACK を実行したタイミングで解放されます。

逆に言うと、これらを実行するまでロックは保持され続けます。

たとえば、UPDATE や INSERT などの更新処理では排他ロック(Xロック)が取得され、その状態のまま COMMIT しないと、他のトランザクションは同じデータにアクセスできません。

この状態が続くと、他の処理はロック待ち(Lock Wait)となり、処理遅延やタイムアウトの原因になります。

特に注意が必要なのは以下のようなケースです。

  • 長時間 COMMIT されないトランザクション
  • 大量データを一括更新するバッチ処理
  • カーソルを開いたままの長時間処理

このような状況ではロックが長時間保持され、並行処理性能が大きく低下します。

そのため、設計および運用では以下を意識することが重要です。

  • トランザクションはできるだけ短くする
  • 適切なタイミングで COMMIT を実行する
  • バッチ処理は分割して実行する

ロックの保持期間はシンプルな仕組みですが、性能問題や障害の原因になりやすいポイントです。
そのため、「いつロックが解放されるのか」を正しく理解しておくことが重要です。


ロックエスカレーション

ロックエスカレーションとは、多数の行ロックを1つの表ロックに変換する仕組みです。
主にメモリ(ロックリスト)の使用量を抑えるために発生します。

ロックエスカレーションは以下の動きです。

  • 行ロックが大量に取得される
  • メモリ使用量が増加
  • 一定条件を超える
  • 行ロック → 表ロックへ変換

イメージ

変換前:
A表の複数行にロック(12行目、30行目、99行目…)

変換後:
A表全体に表ロック

メモリは削減できますが、ロック範囲が一気に広がります。


ロック情報とメモリ(LOCKLIST)

Db2ではロック情報は以下のように管理されます。

  • ロック情報はロック・リスト(LOCKLIST)というメモリ領域に保存
  • データベース全体で1つを共有
  • 最大サイズは LOCKLIST パラメータで制御
  • 各アプリケーションはこの領域を共有して使用

発生条件(原因)

ロックエスカレーションは主に2パターンで発生します。

アプリケーション単位での上限超過(maxlocks)

  • 1トランザクションが大量のロックを保持
  • maxlocks の割合を超過
  • 最もロック数が多い表が対象

データベース全体のメモリ不足(locklist)

  • 全体のロックメモリが locklist 上限に到達
  • 最もロックを消費しているトランザクションが対象

影響

ロックエスカレーションが起きると、性能劣化のトリガーになることが多いです。

  • 行単位 → 表単位になる
  • 他トランザクションがその表にアクセスできなくなる
  • 並行処理性能が大きく低下

回避方法

ロックエスカレーションは設計と運用で回避できます。

トランザクションを小さくする

  • 頻繁にCOMMIT
  • バッチ処理は分割

分離レベルを見直す

  • 不要に強い分離レベルを使わない
  • ロック範囲を最小化

大量更新時は明示的に表ロック

  • あらかじめ表ロックを取得
  • 処理後すぐCOMMIT

パラメータ調整

パラメータ内容
LOCKLISTロックメモリの総量
MAXLOCKS1アプリが使える割合

※現在は多くの環境で AUTOMATIC がデフォルト
→ 通常は自動調整されるが、負荷が高い場合は見直し検討


まとめ

Db2のロックは以下を理解しておくことが重要です。

  • ロックは排他制御の基本
  • 互換性(S/U/X)が最重要
  • ロック範囲が広いほど性能悪化
  • COMMITしないと解放されない
  • ロックエスカレーションに注意

特に、

  • ロック待ち=性能問題の原因
  • 未コミット=障害の原因

になりやすいため、設計段階から意識しておくことが重要です。

コメント

タイトルとURLをコピーしました