LatchとLockを混同したまま障害報告書を書いてしまい、指摘を受けたことがあります。両者の違いとAWR上での見分け方を、そのときの反省とともに整理しました。
LatchとLockの違い
図1: LatchとLock競合の診断フロー
Oracleにおける「競合」には大きく Latch(ラッチ)と Lock(Enqueue) の2種類があります。 症状が似ていますが、原因と対処が異なります。
| 種類 | 概要 | 保持時間 | 主な競合 |
|---|---|---|---|
| Latch | Oracle内部のメモリ構造を保護する軽量ロック | マイクロ〜ミリ秒 | バッファキャッシュ、ライブラリキャッシュ、共有プール |
| Lock(Enqueue) | SQL/DML操作によるユーザーレベルのロック | 秒〜分以上 | 行ロック、表ロック、シーケンス、テーブル定義 |
Wait/Undo/Latchセクション全体の定義は PART 08 — Wait / Undo / Latch 詳細(定義書) を参照。
Latch Activity Statistics の読み方
AWRの Latch Activity セクションでLatch競合の発生状況を確認します。
| 列名 | 意味 | 注目ポイント |
|---|---|---|
| Get Requests | Latch取得要求数 | — |
| Pct Get Miss | 取得失敗率 | 0.1%超が問題の目安 |
| Avg Slps/Miss | ミスあたりの平均スリープ回数 | 高いほど深刻な競合 |
| NoWait Requests | ノーウェイトモードの要求数 | — |
主要なLatch名と原因:
| Latch名 | 原因 | 対処 |
|---|---|---|
| cache buffers chains | 特定ブロックへのアクセス集中(ホットブロック) | 対象テーブルを小さく分割、パーティション化、キャッシュ分散 |
| library cache | ハードパース多発 | バインド変数使用、cursor_sharing設定 |
| shared pool | 共有プール断片化・サイズ不足 | shared_pool_size増加、AMM使用 |
| row cache objects | データディクショナリキャッシュ不足 | shared_pool_size増加 |
Enqueue(Lock)待機の読み方
Enqueue Activity セクションでLock(Enqueue)の種類ごとの待機状況を確認します。
| Enqueue種類 | 意味 | 原因と対処 |
|---|---|---|
| TX (Transaction) | 行レベルのトランザクションロック | コミット遅延・長時間トランザクション → コミット頻度見直し |
| TM (DML) | テーブルレベルのDMLロック | 外部キー制約のインデックスなし → FK列にインデックス追加 |
| ST (Space Transaction) | 空間管理(エクステント割り当て)のロック | セグメントの自動拡張が頻発 → 初期サイズ調整 |
| HW (Segment High Water) | セグメントハイウォーターマーク更新のロック | 大量INSERT → APPEND hintsや配列INSERTを使用 |
Buffer Busy Waits の読み方
Buffer Wait Statistics セクションで、バッファの競合が発生しているオブジェクトを確認します。
| Class | 意味 | 対処 |
|---|---|---|
| data block | 通常データブロックの競合 | ホットブロック → パーティション化、フリーリスト増加(PCTFREE/INITRANS見直し) |
| segment header | セグメントヘッダーの競合 | フリーリスト(FREELIST GROUPS)の増加 |
| undo header / undo block | UNDOブロックの競合 | UNDOセグメント数の増加 |
競合症状の見分け方と誤りやすいパターン
Latch競合とLock競合は症状が似ているが原因と対処が異なる。誤診すると効果のない対処を繰り返すことになる。
| 症状 | 誤った判断 | 正しい確認方法 |
|---|---|---|
| buffer busy waitsが多い | Buffer Cache不足と判断してSGAを増やす | Buffer Wait StatisticsでClassを確認。data blockならホットブロック対策(パーティション化等)が有効 |
| enq: TX - row lock waitが多い | テーブルロックなのでLOCK TABLE文を疑う | TXはトランザクションロック(行レベル)。DBA_BLOCKERSで長時間コミットしていないセッションを特定 |
| library cache latchのMiss率が高い | Shared Poolが小さいと判断してshared_pool_sizeを増やす | Hard Parsesも確認。バインド変数未使用が原因の場合はアプリ修正が先。CURSOR_SHARINGは応急処置 |
| ST enqueue(Space Transaction)待機が出る | テーブルやインデックスへの競合と誤解する | セグメントの自動拡張(AUTOEXTEND)が頻発しているサインで、初期サイズを大きく設定することで解消できる |
競合解消の方向性
1
Latch Miss率が高い → Latch名で原因を特定
cache buffers chains → ホットブロック対策 / library cache → バインド変数使用
2
enq: TX - row lock → 長時間トランザクションを特定
DBA_BLOCKERS / DBA_WAITERSビューで原因セッションを特定
3
buffer busy waits が data block → Segment Statisticsで熱いオブジェクトを特定