STATSPACK Enqueue Activity Analysis (penqueue.sql)
What This Script Does
Section titled “What This Script Does”This script analyzes enqueue (lock) activity from STATSPACK history by:
- Tracking enqueue requests, successful gets, and failed gets
- Calculating wait counts and cumulative wait times
- Computing average wait times for each enqueue type
- Supporting date range and enqueue type filtering
- Showing delta values between snapshots for accurate metrics
- Supporting RAC environments with instance filtering
Script
Section titled “Script”rem penqueue.sqlremset lines 132remcol SNAP_ID format 999999 heading 'SNAP ID'col instance_number format 99 head 'INST'col snap_time format a15 heading 'SNAP TIME'col EVENT format a35 heading 'EVENT'col total_waits format b999,999,990 heading 'TOTAL WAITS'col waits_per_sec format b99,990 heading 'WAITS|PER|SEC'col timeout_pct format b990.0 heading 'TIMEOUT|PCT'col time_waited_micro format b999,999,990 heading 'TIME WAITED(ms)'col avg_wait format 990.0 heading 'AVG|WAIT|TIME(ms)'remdefine start_dt='&start_date'define end_dt='&end_date'define nam='&name'define instno='&inst_no'remttitle 'Enqueue Activity (&nam)'remcol ename format a2 heading 'Eq';col reqs format 999,999,990 heading 'Requests';col sreq format 999,999,990 heading 'Succ Gets';col freq format 99,999,990 heading 'Failed Gets';col waits format 99,999,990 heading 'Waits';col awttm format 9,999,999.99 heading 'Avg Wt|Time (ms)' just c;col wttm format 999,999,999 heading 'Wait|Time (s)' just c;remclear breakclear computeremselect e.snap_id , to_char(e.snap_time, 'mm/dd hh24:mi:ss') snap_time , se.eq_type ename , e.instance_number , se.total_req# - nvl(sb.total_req#,0) reqs , se.succ_req# - nvl(sb.succ_req#,0) sreq , se.failed_req# - nvl(sb.failed_req#,0) freq , se.total_wait# - nvl(sb.total_wait#,0) waits , decode( (se.total_wait# - nvl(sb.total_wait#,0)) , 0, to_number(NULL) , ( (se.cum_wait_time - nvl(sb.cum_wait_time,0)) / (se.total_wait# - nvl(sb.total_wait#,0)) ) ) awttm , (se.cum_wait_time - nvl(sb.cum_wait_time,0))/1000 wttmfrom stats$snapshot e, stats$snapshot b, stats$enqueue_stat sb, stats$enqueue_stat sewhere b.snap_id = (select max(x.snap_id) from stats$snapshot x where x.snap_id < e.snap_id and x.dbid = e.dbid and x.instance_number = e.instance_number) and b.dbid = e.dbid and b.instance_number = e.instance_number and se.snap_id = e.snap_id and se.dbid = e.dbid and sb.snap_id = b.snap_id and sb.dbid = b.dbid and e.instance_number like nvl('&instno','%') and e.snap_time >= nvl(to_date('&start_dt'), trunc(sysdate)) and e.snap_time <= nvl(to_date('&end_dt'), sysdate) + 1 and sb.eq_type = se.eq_type and upper(se.eq_type) like nvl(upper('&nam'),'%') order by e.snap_time, se.eq_type, e.instance_number/remundefine start_dtundefine end_dtundefine namundefine instno
SQL> @penqueue.sqlEnter value for start_date: 01-JAN-2025Enter value for end_date: 07-JAN-2025Enter value for name: TXEnter value for inst_no: 1
Parameters
Section titled “Parameters”- start_date: Beginning date for analysis (DD-MON-YYYY format, defaults to today)
- end_date: End date for analysis (DD-MON-YYYY format, defaults to today)
- name: Enqueue type filter (TX, TM, etc., % for all types)
- inst_no: Instance number for RAC (% for all instances)
Required Privileges
Section titled “Required Privileges”- SELECT on STATS$SNAPSHOT
- SELECT on STATS$ENQUEUE_STAT
- STATSPACK must be installed and collecting data
Sample Output
Section titled “Sample Output”Enqueue Activity (TX)
SNAP ID SNAP TIME Eq INST Requests Succ Gets Failed Gets Waits Avg Wt Wait Time (ms) Time (s)------- --------------- -- ---- ------------ ------------ ----------- ---------- ----------- ----------- 12345 01/01 10:00:00 TX 1 456,789 456,745 44 234 125.5 29 12346 01/01 11:00:00 TX 1 523,456 523,398 58 312 156.8 49 12347 01/01 12:00:00 TX 1 678,901 678,234 667 1,234 234.5 289 12348 01/01 13:00:00 TX 1 712,345 712,123 222 456 189.3 86
Key Output Columns
Section titled “Key Output Columns”- SNAP ID: STATSPACK snapshot identifier
- SNAP TIME: Time of the snapshot
- Eq: Enqueue type (2-character code)
- INST: Instance number (RAC)
- Requests: Total enqueue requests
- Succ Gets: Successful enqueue acquisitions
- Failed Gets: Failed acquisition attempts
- Waits: Number of wait events
- Avg Wt Time (ms): Average wait time in milliseconds
- Wait Time (s): Total wait time in seconds
Understanding Enqueue Types
Section titled “Understanding Enqueue Types”Common Enqueue Types
Section titled “Common Enqueue Types”- TX: Transaction lock (row-level locking)
- TM: Table lock (DML operations)
- ST: Space transaction lock
- HW: High water mark lock
- SQ: Sequence cache lock
- CF: Control file transaction
- TC: Thread checkpoint
Interpreting Metrics
Section titled “Interpreting Metrics”- High Failed Gets: Indicates contention
- Long Average Wait Times: Blocking issues
- Increasing Waits: Growing contention
- Failed Gets ≈ Waits: Normal blocking pattern
Performance Analysis
Section titled “Performance Analysis”Contention Patterns
Section titled “Contention Patterns”-- Focus on enqueues with high wait timesEnter value for name: %-- Then look for high values in Avg Wt Time column
Transaction Lock Analysis
Section titled “Transaction Lock Analysis”-- Monitor TX locks specificallyEnter value for name: TX-- High TX waits indicate row-level contention
Table Lock Monitoring
Section titled “Table Lock Monitoring”-- Check for TM lock issuesEnter value for name: TM-- High TM waits suggest table-level locking problems
Common Use Cases
Section titled “Common Use Cases”-
Blocking Analysis
- Identify peak contention periods
- Track blocking patterns over time
- Correlate with application activity
-
Capacity Planning
- Monitor enqueue activity growth
- Identify scaling bottlenecks
- Plan for concurrency increases
-
Performance Tuning
- Find hot objects causing contention
- Optimize locking strategies
- Validate application changes
Troubleshooting Patterns
Section titled “Troubleshooting Patterns”High TX Contention
Section titled “High TX Contention”Symptoms: High TX waits and failed gets Common Causes:
- Unindexed foreign keys
- Hot rows or blocks
- Long-running transactions
- Application design issues
TM Lock Escalation
Section titled “TM Lock Escalation”Symptoms: Increasing TM waits Common Causes:
- Missing indexes on FK columns
- Full table locks from DDL
- Exclusive table locks
Sequence Contention
Section titled “Sequence Contention”Symptoms: High SQ enqueue waits Solutions:
- Increase sequence cache size
- Use NOORDER option
- Consider identity columns (12c+)
Historical Trend Analysis
Section titled “Historical Trend Analysis”Daily Patterns
Section titled “Daily Patterns”-- Run for a week to see daily patternsEnter value for start_date: 01-JAN-2025Enter value for end_date: 07-JAN-2025Enter value for name: %
Peak Hour Identification
Section titled “Peak Hour Identification”Look for patterns in the SNAP TIME column:
- Morning login surge
- Batch processing windows
- End-of-day processing
RAC-Specific Considerations
Section titled “RAC-Specific Considerations”Cross-Instance Analysis
Section titled “Cross-Instance Analysis”-- Compare enqueue activity across nodesEnter value for inst_no: %-- Look for imbalanced activity
Global Enqueue Monitoring
Section titled “Global Enqueue Monitoring”Some enqueues are global in RAC:
- IV: Instance validation
- DD: Global deadlock detection
- DX: Distributed transaction
Integration Strategies
Section titled “Integration Strategies”With Current Waits
Section titled “With Current Waits”- Use this script for historical trends
- Use V$ENQUEUE_STAT for current state
- Correlate patterns with business cycles
With Blocking Scripts
Section titled “With Blocking Scripts”- Identify contention periods here
- Use blocking session scripts during peaks
- Trace specific problem transactions
Best Practices
Section titled “Best Practices”-
Regular Monitoring
- Check daily for unusual patterns
- Establish baseline metrics
- Alert on threshold breaches
-
Proactive Analysis
- Monitor failed gets trends
- Watch average wait time changes
- Track requests growth
-
Problem Resolution
- Focus on enqueues with highest wait times
- Investigate sudden spikes
- Document recurring patterns
Advanced Analysis
Section titled “Advanced Analysis”Enqueue Efficiency Ratio
Section titled “Enqueue Efficiency Ratio”-- Calculate success rateSELECT eq_type, SUM(succ_req#) successful, SUM(failed_req#) failed, ROUND(SUM(succ_req#) * 100 / (SUM(succ_req#) + SUM(failed_req#)), 2) success_rateFROM stats$enqueue_statGROUP BY eq_typeORDER BY success_rate;
Wait Time Distribution
Section titled “Wait Time Distribution”-- Analyze wait time patternsSELECT eq_type, MIN(avg_wait_time) min_wait, MAX(avg_wait_time) max_wait, AVG(avg_wait_time) avg_wait, STDDEV(avg_wait_time) stddev_waitFROM ( -- Subquery with main query logic)GROUP BY eq_type;
Troubleshooting
Section titled “Troubleshooting”No Data Returned
Section titled “No Data Returned”- Verify STATSPACK is installed
- Check snapshot collection is running
- Ensure date range has snapshots
Missing Enqueue Types
Section titled “Missing Enqueue Types”- Some enqueues may not have activity
- Check V$ENQUEUE_STAT for current activity
- Verify enqueue type spelling
Performance Issues
Section titled “Performance Issues”- Limit date range for faster execution
- Use specific enqueue types when possible
- Consider summary tables for long-term analysis