-- =====================================================================
-- GL ARCHIVE AND PURGE - READ-ONLY DIAGNOSTIC SQL
-- SQL_ID 6vhqjj8bwpga6 | EBS 12.2 / DB 19c | DEV03
-- =====================================================================
SET LINESIZE 250 PAGESIZE 200 LONG 1000000 LONGCHUNKSIZE 1000000
SET SERVEROUTPUT ON SIZE UNLIMITED
COL prog FORMAT A40
COL argument_text FORMAT A60
COL object_name FORMAT A30
COL event FORMAT A40
-- ---------------------------------------------------------------------
-- A1. Running request details
-- ---------------------------------------------------------------------
SELECT r.request_id,
p.user_concurrent_program_name prog,
r.phase_code,
r.status_code,
r.actual_start_date,
ROUND((SYSDATE - r.actual_start_date) * 1440) elapsed_min,
r.argument_text,
r.oracle_process_id spid,
r.os_process_id,
r.logfile_node_name,
r.logfile_name
FROM apps.fnd_concurrent_requests r
JOIN apps.fnd_concurrent_programs_vl p
ON p.concurrent_program_id = r.concurrent_program_id
AND p.application_id = r.program_application_id
WHERE r.phase_code = 'R'
AND UPPER(p.user_concurrent_program_name) LIKE '%ARCHIVE%PURGE%';
-- ---------------------------------------------------------------------
-- B1. Database session for the request (via SPID from A1)
-- ---------------------------------------------------------------------
SELECT s.inst_id,
s.sid,
s.serial#,
s.sql_id,
s.sql_child_number,
s.sql_exec_id,
s.sql_exec_start,
s.event,
s.state,
s.wait_time_micro,
s.blocking_instance,
s.blocking_session,
s.final_blocking_session,
s.row_wait_obj#,
s.module,
s.action
FROM gv$session s
JOIN gv$process p
ON p.addr = s.paddr
AND p.inst_id = s.inst_id
WHERE p.spid = '&spid';
-- ---------------------------------------------------------------------
-- B2. Object the session is currently waiting on
-- ---------------------------------------------------------------------
SELECT s.inst_id,
s.sid,
s.event,
s.p1 file#,
s.p2 block#,
o.owner,
o.object_name,
o.object_type
FROM gv$session s
LEFT JOIN dba_objects o
ON o.object_id = s.row_wait_obj#
WHERE s.inst_id = &inst
AND s.sid = &sid;
-- ---------------------------------------------------------------------
-- C1. Transaction progress (run twice, 5 minutes apart)
-- ---------------------------------------------------------------------
SELECT t.inst_id,
t.start_time,
t.status,
t.used_ublk,
t.used_urec,
t.log_io,
t.phy_io,
DECODE(BITAND(t.flag, 128), 128, 'ROLLING BACK', 'FORWARD') direction
FROM gv$transaction t
JOIN gv$session s
ON s.taddr = t.addr
AND s.inst_id = t.inst_id
WHERE s.inst_id = &inst
AND s.sid = &sid;
-- ---------------------------------------------------------------------
-- C2. Rollback progress (only if C1 shows ROLLING BACK or session gone)
-- ---------------------------------------------------------------------
SELECT inst_id,
usn,
state,
undoblockstotal,
undoblocksdone,
ROUND(undoblocksdone / NULLIF(undoblockstotal, 0) * 100, 2) pct_done
FROM gv$fast_start_transactions;
-- ---------------------------------------------------------------------
-- D1. Session statistics delta over 5 minutes
-- ---------------------------------------------------------------------
DECLARE
TYPE t IS TABLE OF NUMBER INDEX BY VARCHAR2(64);
a t;
b t;
k VARCHAR2(64);
PROCEDURE snap (x IN OUT t) IS
BEGIN
FOR r IN (SELECT n.name, st.value
FROM gv$sesstat st
JOIN v$statname n ON n.statistic# = st.statistic#
WHERE st.inst_id = &inst
AND st.sid = &sid
AND n.name IN ('session logical reads',
'physical reads',
'db block changes',
'redo size',
'undo change vector size',
'CPU used by this session'))
LOOP
x(r.name) := r.value;
END LOOP;
END;
BEGIN
snap(a);
DBMS_SESSION.SLEEP(300);
snap(b);
k := a.FIRST;
WHILE k IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE(RPAD(k, 30) || LPAD(b(k) - a(k), 18));
k := a.NEXT(k);
END LOOP;
END;
/
-- ---------------------------------------------------------------------
-- D2. Cursor-level execution statistics (cumulative)
-- ---------------------------------------------------------------------
SELECT inst_id,
child_number,
plan_hash_value,
executions,
rows_processed,
buffer_gets,
disk_reads,
physical_read_bytes,
ROUND(elapsed_time / 1e6) ela_s,
ROUND(cpu_time / 1e6) cpu_s,
ROUND(user_io_wait_time / 1e6) io_s,
last_active_time
FROM gv$sql
WHERE sql_id = '6vhqjj8bwpga6';
-- ---------------------------------------------------------------------
-- D3. Captured bind values (all child cursors)
-- ---------------------------------------------------------------------
SELECT inst_id,
child_number,
name,
position,
datatype_string,
value_string,
last_captured
FROM gv$sql_bind_capture
WHERE sql_id = '6vhqjj8bwpga6'
ORDER BY inst_id, child_number, position;
-- ---------------------------------------------------------------------
-- E1. ASH: time by plan line and object (Diagnostics Pack required)
-- ---------------------------------------------------------------------
SELECT a.sql_exec_id,
a.sql_plan_line_id,
a.sql_plan_operation,
o.object_name,
o.object_type,
a.event,
COUNT(*) samples
FROM gv$active_session_history a
LEFT JOIN dba_objects o
ON o.object_id = a.current_obj#
WHERE a.session_id = &sid
AND a.session_serial# = &serial
AND a.sample_time > SYSTIMESTAMP - INTERVAL '60' MINUTE
GROUP BY a.sql_exec_id, a.sql_plan_line_id, a.sql_plan_operation,
o.object_name, o.object_type, a.event
ORDER BY samples DESC;
-- ---------------------------------------------------------------------
-- E2. ASH: executions of this SQL over the request lifetime
-- ---------------------------------------------------------------------
SELECT a.sql_exec_id,
MIN(a.sql_exec_start) exec_start,
MIN(a.sample_time) first_seen,
MAX(a.sample_time) last_seen,
COUNT(*) samples
FROM dba_hist_active_sess_history a
WHERE a.sql_id = '6vhqjj8bwpga6'
AND a.sample_time > TO_DATE('23-SEP-2026 06:00', 'DD-MON-YYYY HH24:MI')
GROUP BY a.sql_exec_id
ORDER BY exec_start;
-- ---------------------------------------------------------------------
-- E3. Segment statistics (license-free; run twice, 5 minutes apart)
-- ---------------------------------------------------------------------
SELECT owner,
object_name,
statistic_name,
value
FROM gv$segment_statistics
WHERE ( (owner = 'GL' AND object_name LIKE 'GL_BALANCES%')
OR object_name = 'XXGL_BALANCES_IND1')
AND statistic_name IN ('physical reads', 'logical reads', 'db block changes')
ORDER BY object_name, statistic_name;
-- ---------------------------------------------------------------------
-- F1. Current execution plan with peeked binds
-- ---------------------------------------------------------------------
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('6vhqjj8bwpga6', NULL, 'TYPICAL +PEEKED_BINDS'));
-- ---------------------------------------------------------------------
-- F2. Historical plans and runtimes (AWR)
-- ---------------------------------------------------------------------
SELECT s.snap_id,
sn.begin_interval_time,
s.plan_hash_value,
s.executions_delta,
s.rows_processed_delta,
ROUND(s.elapsed_time_delta / 1e6) ela_s,
s.buffer_gets_delta,
s.disk_reads_delta
FROM dba_hist_sqlstat s
JOIN dba_hist_snapshot sn
ON sn.snap_id = s.snap_id
AND sn.instance_number = s.instance_number
AND sn.dbid = s.dbid
WHERE s.sql_id = '6vhqjj8bwpga6'
ORDER BY s.snap_id;
-- ---------------------------------------------------------------------
-- G1. SQL Monitor: estimated vs actual rows per line (Tuning Pack required)
-- ---------------------------------------------------------------------
SELECT sql_exec_id,
plan_line_id,
plan_operation,
plan_options,
plan_object_name,
plan_cardinality e_rows,
output_rows a_rows,
starts,
physical_read_requests,
physical_read_bytes
FROM gv$sql_plan_monitor
WHERE sql_id = '6vhqjj8bwpga6'
AND status = 'EXECUTING'
ORDER BY plan_line_id;
-- ---------------------------------------------------------------------
-- G2. SQL Monitor text report (Tuning Pack required)
-- ---------------------------------------------------------------------
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(
sql_id => '6vhqjj8bwpga6',
type => 'TEXT',
report_level => 'ALL')
FROM dual;
-- ---------------------------------------------------------------------
-- H1. Blocking sessions
-- ---------------------------------------------------------------------
SELECT inst_id,
sid,
serial#,
blocking_instance,
blocking_session,
event,
seconds_in_wait,
sql_id
FROM gv$session
WHERE blocking_session IS NOT NULL;
-- ---------------------------------------------------------------------
-- H2. Locks held or requested by the purge session
-- ---------------------------------------------------------------------
SELECT l.inst_id,
l.sid,
l.type,
l.id1,
l.id2,
l.lmode,
l.request,
l.block,
o.object_name
FROM gv$lock l
LEFT JOIN dba_objects o
ON o.object_id = l.id1
WHERE l.inst_id = &inst
AND l.sid = &sid;
-- ---------------------------------------------------------------------
-- H3. Storage latency, CPU, and redo rate (last 60 seconds)
-- ---------------------------------------------------------------------
SELECT inst_id,
metric_name,
ROUND(value, 2) val,
metric_unit
FROM gv$sysmetric
WHERE group_id = 2
AND metric_name IN ('Average Synchronous Single-Block Read Latency',
'Host CPU Utilization (%)',
'Physical Reads Per Sec',
'Redo Generated Per Sec');
-- ---------------------------------------------------------------------
-- H4. Per-datafile read latency (last interval)
-- ---------------------------------------------------------------------
SELECT f.file_name,
m.physical_reads,
ROUND(m.average_read_time * 10, 2) avg_read_ms
FROM v$filemetric m
JOIN dba_data_files f
ON f.file_id = m.file_id
ORDER BY m.average_read_time DESC
FETCH FIRST 20 ROWS ONLY;
-- ---------------------------------------------------------------------
-- H5. Undo pressure (last hour)
-- ---------------------------------------------------------------------
SELECT begin_time,
end_time,
undoblks,
txncount,
maxquerylen,
ssolderrcnt,
nospaceerrcnt
FROM v$undostat
WHERE begin_time > SYSDATE - 1/24
ORDER BY begin_time;
-- ---------------------------------------------------------------------
-- H6. Competing active workload
-- ---------------------------------------------------------------------
SELECT inst_id,
sid,
username,
module,
sql_id,
event,
wait_class
FROM gv$session
WHERE status = 'ACTIVE'
AND type = 'USER'
AND wait_class <> 'Idle'
ORDER BY inst_id, module;
-- ---------------------------------------------------------------------
-- H7. Other running concurrent requests
-- ---------------------------------------------------------------------
SELECT r.request_id,
p.user_concurrent_program_name prog,
r.actual_start_date,
ROUND((SYSDATE - r.actual_start_date) * 1440) elapsed_min
FROM apps.fnd_concurrent_requests r
JOIN apps.fnd_concurrent_programs_vl p
ON p.concurrent_program_id = r.concurrent_program_id
AND p.application_id = r.program_application_id
WHERE r.phase_code = 'R'
ORDER BY r.actual_start_date;
-- ---------------------------------------------------------------------
-- S1. Table statistics
-- ---------------------------------------------------------------------
SELECT owner,
table_name,
num_rows,
blocks,
sample_size,
stattype_locked,
stale_stats,
last_analyzed
FROM dba_tab_statistics
WHERE owner = 'GL'
AND table_name = 'GL_BALANCES';
-- ---------------------------------------------------------------------
-- S2. Index statistics
-- ---------------------------------------------------------------------
SELECT index_name,
blevel,
leaf_blocks,
num_rows,
distinct_keys,
clustering_factor,
sample_size,
stattype_locked,
stale_stats,
last_analyzed
FROM dba_ind_statistics
WHERE table_owner = 'GL'
AND table_name = 'GL_BALANCES'
ORDER BY index_name;
-- ---------------------------------------------------------------------
-- S3. Column statistics and histograms
-- ---------------------------------------------------------------------
SELECT column_name,
num_distinct,
num_nulls,
density,
histogram,
num_buckets,
sample_size,
last_analyzed
FROM dba_tab_col_statistics
WHERE owner = 'GL'
AND table_name = 'GL_BALANCES'
AND column_name IN ('LEDGER_ID', 'PERIOD_NAME', 'ACTUAL_FLAG', 'BUDGET_VERSION_ID');
-- ---------------------------------------------------------------------
-- S4. Histogram endpoints for ACTUAL_FLAG and LEDGER_ID (if present)
-- ---------------------------------------------------------------------
SELECT column_name,
endpoint_number,
endpoint_value,
endpoint_actual_value
FROM dba_tab_histograms
WHERE owner = 'GL'
AND table_name = 'GL_BALANCES'
AND column_name IN ('ACTUAL_FLAG', 'LEDGER_ID')
ORDER BY column_name, endpoint_number;
-- ---------------------------------------------------------------------
-- S5. DML since last analyze
-- ---------------------------------------------------------------------
SELECT table_owner,
table_name,
inserts,
updates,
deletes,
truncated,
timestamp
FROM dba_tab_modifications
WHERE table_owner = 'GL'
AND table_name = 'GL_BALANCES';
-- ---------------------------------------------------------------------
-- S6. Pending statistics
-- ---------------------------------------------------------------------
SELECT *
FROM dba_tab_pending_stats
WHERE owner = 'GL'
AND table_name = 'GL_BALANCES';
-- ---------------------------------------------------------------------
-- S7. Extended statistics (column groups)
-- ---------------------------------------------------------------------
SELECT extension_name,
extension,
creator,
droppable
FROM dba_stat_extensions
WHERE owner = 'GL'
AND table_name = 'GL_BALANCES';
-- ---------------------------------------------------------------------
-- S8. Statistics history (restore points)
-- ---------------------------------------------------------------------
SELECT owner,
table_name,
stats_update_time
FROM dba_tab_stats_history
WHERE owner = 'GL'
AND table_name = 'GL_BALANCES'
ORDER BY stats_update_time DESC;
-- ---------------------------------------------------------------------
-- S9. EBS histogram column registration
-- ---------------------------------------------------------------------
SELECT *
FROM apps.fnd_histogram_cols
WHERE table_name = 'GL_BALANCES';
-- ---------------------------------------------------------------------
-- X1. Full column list of all GL_BALANCES indexes
-- ---------------------------------------------------------------------
SELECT index_owner,
index_name,
column_position,
column_name,
descend
FROM dba_ind_columns
WHERE table_owner = 'GL'
AND table_name = 'GL_BALANCES'
ORDER BY index_name, column_position;
-- ---------------------------------------------------------------------
-- X2. Index size
-- ---------------------------------------------------------------------
SELECT owner,
segment_name,
segment_type,
ROUND(bytes / 1024 / 1024 / 1024, 2) size_gb
FROM dba_segments
WHERE segment_name IN ('GL_BALANCES', 'GL_BALANCES_N1', 'GL_BALANCES_N2',
'GL_BALANCES_N3', 'GL_BALANCES_N4', 'XXGL_BALANCES_IND1')
ORDER BY bytes DESC;
-- ---------------------------------------------------------------------
-- X3. Index usage tracking (19c)
-- ---------------------------------------------------------------------
SELECT owner,
name,
total_access_count,
total_exec_count,
total_rows_returned,
last_used
FROM dba_index_usage
WHERE name IN ('GL_BALANCES_N1', 'GL_BALANCES_N2', 'GL_BALANCES_N3',
'GL_BALANCES_N4', 'XXGL_BALANCES_IND1');
-- =====================================================================
-- CLONE / OFF-HOURS ONLY - these read GL_BALANCES and add I/O load
-- =====================================================================
-- ---------------------------------------------------------------------
-- Z1. Period row count by ACTUAL_FLAG
-- ---------------------------------------------------------------------
SELECT actual_flag,
COUNT(*) cnt
FROM gl.gl_balances
WHERE period_name = '2000-12'
GROUP BY actual_flag;
-- ---------------------------------------------------------------------
-- Z2. Period row count by LEDGER_ID and ACTUAL_FLAG
-- ---------------------------------------------------------------------
SELECT ledger_id,
actual_flag,
COUNT(*) cnt
FROM gl.gl_balances
WHERE period_name = '2000-12'
GROUP BY ledger_id, actual_flag
ORDER BY cnt DESC;
-- ---------------------------------------------------------------------
-- Z3. Exact rows matching the captured purge predicates
-- ---------------------------------------------------------------------
SELECT COUNT(*) qualifying_rows
FROM gl.gl_balances
WHERE ledger_id = 50
AND period_name = '2000-12'
AND actual_flag = 'A';
-- ---------------------------------------------------------------------
-- Z4. Remaining volume per period for ledger 50
-- ---------------------------------------------------------------------
SELECT period_name,
actual_flag,
COUNT(*) cnt
FROM gl.gl_balances
WHERE ledger_id = 50
GROUP BY period_name, actual_flag
ORDER BY period_name, actual_flag;
-- ---------------------------------------------------------------------
-- Z5. Compare N2 vs XXGL_BALANCES_IND1 access path (clone only)
-- ---------------------------------------------------------------------
SELECT /*+ GATHER_PLAN_STATISTICS INDEX(gb GL_BALANCES_N2) */
COUNT(*)
FROM gl.gl_balances gb
WHERE gb.ledger_id = 50
AND gb.period_name = '2000-12'
AND gb.actual_flag = 'A';
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));
SELECT /*+ GATHER_PLAN_STATISTICS INDEX(gb XXGL_BALANCES_IND1) */
COUNT(*)
FROM gl.gl_balances gb
WHERE gb.ledger_id = 50
AND gb.period_name = '2000-12'
AND gb.actual_flag = 'A';
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));
-- =====================================================================
-- END
-- =====================================================================