Chapter 22 · Observability and Diagnostics: AWR, ASH, ADDM, Wait Events, and Tracing

Dynamic Performance Views for Sessions, SQL, Locks, I/O, Memory, and Instance Health

Answer concrete live incident questions from Oracle dynamic performance views, using bounded snapshots and container-aware interpretation instead of treating cumulative/transient V$ state as durable history.

Advanced125–145 minutesLive V$ blocking/SQL/resource diagnostic labOracle AI Database 26ai · RU 23.26.3 baselineCore dynamic views · no pack requiredLast reviewed: August 2026

Learning outcomes

ServiceHub users report “the database is slow right now.” Before reaching for historical reports, the DBA needs to answer immediate questions: Which sessions are active? Which SQL are they running? Is one session blocking another? Are reads/writes increasing? Is memory pressure visible? Are process/session limits near their configured ceilings? Oracle's dynamic performance views—the V$/GV$ family—expose live instance state and cumulative counters.

01

Use V$SESSION and V$SQL to identify active work without mistaking one sample for history.

02

Diagnose a real row-lock blocker with V$SESSION and V$LOCK, then repair it by ending the correct transaction.

03

Read file I/O, SGA/PGA and resource-limit evidence from pack-independent dynamic views.

04

Explain why cumulative counters require two snapshots and why cursor/session state can disappear.

05

Apply CDB/PDB and RAC scope correctly: V$ is local/current-container-aware; GV$ adds instance identity in RAC.

Generation-time baseline, licensing, scope, and evidence boundary

Mandatory examples target Oracle AI Database Free 26ai, reviewed against RU 23.26.3, SQL Developer 26.2, and SQLcl 26.2.1. Free is limited to 2 foreground CPU cores, 2 GB combined SGA/PGA memory, 12 GB user data, and one installation per logical environment; Oracle provides no Release Update patches or Support service requests for Free. The course CDB/PDB baseline is FREE/FREEPDB1. Core dynamic performance views, DBMS_XPLAN runtime plans, DBMS_MONITOR SQL trace and TKPROF are used as the pack-independent diagnostic lane. Current 26ai licensing includes Oracle Diagnostics Pack and Oracle Tuning Pack in Free, but each is an extra-cost pack on EE/EE-ES. AWR, ADDM and V$ACTIVE_SESSION_HISTORY belong to Diagnostics Pack; Real-Time SQL/PLSQL Monitoring belongs to Tuning Pack and also requires Diagnostics Pack. CONTROL_MANAGEMENT_PACK_ACCESS defaults to DIAGNOSTIC+TUNING on both Free and Enterprise Edition, so a value of DIAGNOSTIC+TUNING proves functional enablement—not that an EE/EE-ES customer purchased the packs. Never query AWR/ASH/ADDM/SQL Monitor merely because the views exist on an EE/EE-ES system whose entitlement is unknown.

1. Dynamic views answer “what is true now?”

V$SESSION exposes session identity/state, V$SQL exposes cursor-level SQL statistics, V$SYSTEM_EVENT/V$SESSION_EVENT expose cumulative waits, and specialized views expose locks, files, memory and configured resource utilization. Most values are memory-derived and reset/recycle with instance restart, session end, cursor aging/reload or object lifecycle.

sql · scope card
SELECT  SYS_CONTEXT('USERENV','CON_NAME') AS con_name,  SYS_CONTEXT('USERENV','CON_ID') AS con_id,  SYS_CONTEXT('USERENV','INSTANCE_NAME') AS instance_nameFROM dual;SELECT instance_name,startup_time,statusFROM v$instance;

2. Active sessions: status, event, SQL and application identity

sql · live user sessions
SELECT  sid,  serial#,  username,  status,  service_name,  module,  action,  client_identifier,  sql_id,  event,  wait_class,  seconds_in_waitFROM v$sessionWHERE type='USER'ORDER BY status DESC,sid;

ACTIVE means the session is executing a database call—not necessarily consuming CPU. An active session can be waiting on I/O, a lock, network or another resource. INACTIVE can be healthy connection-pool idleness.

3. Join the SQL ID to cursor statistics

sql · cursor evidence for one SQL ID
SELECT  sql_id,  child_number,  plan_hash_value,  executions,  rows_processed,  buffer_gets,  disk_reads,  cpu_time,  elapsed_time,  parse_calls,  substr(sql_text,1,120) AS sql_textFROM v$sqlWHERE sql_id=:sql_idORDER BY child_number;

These are cumulative cursor statistics. A high lifetime BUFFER_GETS can simply mean a very frequently executed healthy SQL statement. Normalize by executions and take interval deltas before calling it the current incident cause.

4. Reproducible blocking lab

sql · setup as SERVICEHUB_OWNER
BEGIN  EXECUTE IMMEDIATE 'DROP TABLE sh22_lock_case PURGE';EXCEPTION WHEN OTHERS THEN  IF SQLCODE != -942 THEN RAISE; END IF;END;/CREATE TABLE sh22_lock_case (  case_id NUMBER PRIMARY KEY,  status_code VARCHAR2(12) NOT NULL,  amount NUMBER(10,2) NOT NULL);INSERT INTO sh22_lock_case VALUES(1,'OPEN',100);INSERT INTO sh22_lock_case VALUES(2,'OPEN',200);COMMIT;
sql · Session A — hold the row lock deliberately
BEGIN  DBMS_APPLICATION_INFO.SET_MODULE('SH22_LOCK_LAB','HOLDER');END;/UPDATE sh22_lock_caseSET amount=amount+10WHERE case_id=1;-- Do NOT commit yet.
sql · Session B — blocks on the same row
BEGIN  DBMS_APPLICATION_INFO.SET_MODULE('SH22_LOCK_LAB','WAITER');END;/UPDATE sh22_lock_caseSET status_code='HOLD'WHERE case_id=1;-- This call waits until Session A commits/rolls back or a timeout/interrupt occurs.

5. Diagnose the blocker from a third/admin session

sql · blocking chain evidence
SELECT  sid,  serial#,  module,  action,  status,  event,  wait_class,  seconds_in_wait,  blocking_instance,  blocking_session,  final_blocking_session,  sql_idFROM v$sessionWHERE module='SH22_LOCK_LAB'ORDER BY sid;

The waiter should show an enqueue event such as enq: TX - row lock contention and identify Session A as the blocker. The blocker may show INACTIVE while holding an open transaction—important proof that inactive does not mean harmless.

sql · lock structure evidence
SELECT  sid,  type,  id1,  id2,  lmode,  request,  block,  ctimeFROM v$lockWHERE sid IN (  SELECT sid FROM v$session WHERE module='SH22_LOCK_LAB')ORDER BY type,sid;

The TX enqueue rows expose holder/requester state. They do not tell you whether the business transaction should be committed or rolled back; application/owner context decides the safe repair.

6. Safe repair: end the correct transaction

sql · Session A
ROLLBACK;-- Session B can now proceed with its UPDATE.
sql · Session B
ROLLBACK;BEGIN  DBMS_APPLICATION_INFO.SET_MODULE(NULL,NULL);END;/

Do not kill a blocker as the first reaction. A forced session kill can trigger rollback of a large transaction and prolong the incident while obscuring the business owner of the work.

7. I/O, memory and process/session headroom

sql · datafile I/O counters
SELECT  d.name AS datafile,  f.phyrds,  f.phyblkrd,  f.phywrts,  f.phyblkwrt,  f.readtim,  f.writetimFROM v$filestat fJOIN v$datafile d  ON d.file#=f.file#ORDER BY f.phyrds+f.phywrts DESC;
sql · SGA/PGA evidence
SELECT name,bytesFROM v$sgainfoORDER BY bytes DESC NULLS LAST;SELECT name,value,unitFROM v$pgastatWHERE name IN (  'total PGA allocated',  'maximum PGA allocated',  'total PGA inuse',  'over allocation count',  'cache hit percentage')ORDER BY name;
sql · configured resource headroom
SELECT  resource_name,  current_utilization,  max_utilization,  initial_allocation,  limit_valueFROM v$resource_limitWHERE resource_name IN (  'processes',  'sessions',  'transactions')ORDER BY resource_name;

V$FILESTAT and memory/resource views are cumulative/state evidence. A large number is not automatically a bottleneck. Snapshot them at T1/T2 and correlate deltas with workload volume and OS/storage evidence.

8. Deliberately wrong: sort V$SYSTEM_EVENT by TIME_WAITED and declare the top row the root cause

Lifetime cumulative waits include yesterday's backups, startup work and normal workload. A top wait can be irrelevant to the current five-minute incident. The repair is the core diagnostic discipline of this chapter: capture bounded intervals, classify idle/non-idle waits, correlate with throughput and current sessions, and only then formulate a hypothesis.

9. Cleanup

sql · cleanup
DROP TABLE sh22_lock_case PURGE;

10. Production judgment

Start incidents with cheap live evidence. Restrict catalog access: application users should not receive broad SELECT ANY DICTIONARY merely for monitoring; use a dedicated diagnostic role with narrowly required V_$... grants or an approved catalog role/tool. Preserve timestamps and query output externally because live state disappears.

No optional pack, restart or COMPATIBLE change is required for the core views used here. In RAC use GV$ plus INST_ID; in a PDB understand which rows/counters are container-filtered and use CON_ID where supplied. Lesson 2 converts cumulative views into bounded wait/time-model deltas.

Check your understanding

  1. What does ACTIVE mean in V$SESSION?
  2. Why can an INACTIVE session still block another session?
  3. Why should V$SQL lifetime buffer gets not be treated as current load automatically?
  4. What does V$RESOURCE_LIMIT prove?
  5. Why capture dynamic-view output externally during an incident?
Review the answers

It means the session is inside a database call; it can be on CPU or waiting.

It can hold locks from an uncommitted transaction while the client is idle between calls.

Cursor statistics are cumulative and can represent many healthy past executions; normalize and use interval deltas.

It shows configured/current/high-water utilization for resources such as processes/sessions, not application latency.

Sessions/cursors/memory state and cumulative counters can disappear/reset, so transient evidence needs timestamped preservation.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.