LatchとLockを混同したまま障害報告書を書いてしまい、指摘を受けたことがあります。両者の違いとAWR上での見分け方を、そのときの反省とともに整理しました。

LatchとLockの違い

Latch・Lock競合分析図

図1: LatchとLock競合の診断フロー

Oracleにおける「競合」には大きく Latch(ラッチ)と Lock(Enqueue) の2種類があります。 症状が似ていますが、原因と対処が異なります。

種類概要保持時間主な競合
LatchOracle内部のメモリ構造を保護する軽量ロックマイクロ〜ミリ秒バッファキャッシュ、ライブラリキャッシュ、共有プール
Lock(Enqueue)SQL/DML操作によるユーザーレベルのロック秒〜分以上行ロック、表ロック、シーケンス、テーブル定義

Wait/Undo/Latchセクション全体の定義は PART 08 — Wait / Undo / Latch 詳細(定義書) を参照。

Latch Activity Statistics の読み方

AWRの Latch Activity セクションでLatch競合の発生状況を確認します。

列名意味注目ポイント
Get RequestsLatch取得要求数
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 blockUNDOブロックの競合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で熱いオブジェクトを特定