Files
oracle/idev/sp_purge_30_days_9i.sql

478 lines
14 KiB
MySQL
Raw Permalink Normal View History

2026-03-12 21:23:47 +01:00
-- +----------------------------------------------------------------------------+
-- | Jeffrey M. Hunter |
-- | jhunter@idevelopment.info |
-- | www.idevelopment.info |
-- |----------------------------------------------------------------------------|
-- | Copyright (c) 1998-2012 Jeffrey M. Hunter. All rights reserved. |
-- |----------------------------------------------------------------------------|
-- | DATABASE : Oracle |
-- | FILE : sp_purge_30_days_9i.sql |
-- | CLASS : Statspack |
-- | PURPOSE : This script is responsible for removing all Statspack snapshot |
-- | records older than 30 days. Most of the code contained in this |
-- | script is modeled after the Oracle supplied sppurge.sql script |
-- | but removes by Snapshot date rather than Snapshot IDs. |
-- | |
-- | Note that this script only works with Oracle9i. |
-- | |
-- | NOTE : As with any code, ensure to test this script in a development |
-- | environment before attempting to run it in production. |
-- +----------------------------------------------------------------------------+
SET LINESIZE 145
SET PAGESIZE 9999
SET FEEDBACK off
SET VERIFY off
DEFINE days_to_keep=30
UNDEFINE dbid inst_num hisnapid
WHENEVER SQLERROR EXIT ROLLBACK
SPOOL sp_purge_&days_to_keep._days_9i.lis
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Get database and instance currently connected to. This will be used later |
prompt | in the report along with other metadata to lookup snapshots. |
prompt +----------------------------------------------------------------------------+
SET FEEDBACK off
COLUMN inst_num FORMAT 99999999999999 HEADING "Instance Num." NEW_VALUE inst_num
COLUMN inst_name FORMAT a15 HEADING "Instance Name" NEW_VALUE inst_name
COLUMN db_name FORMAT a10 HEADING "DB Name" NEW_VALUE db_name
COLUMN dbid FORMAT 9999999999 HEADING "DB Id" NEW_VALUE dbid
SELECT
d.dbid dbid
, d.name db_name
, i.instance_number inst_num
, i.instance_name inst_name
FROM
v$database d
, v$instance i
/
VARIABLE dbid NUMBER;
VARIABLE inst_num NUMBER;
VARIABLE inst_name VARCHAR2(20);
VARIABLE db_name VARCHAR2(20);
BEGIN
:dbid := &dbid;
:inst_num := &inst_num;
:inst_name := '&inst_name';
:db_name := '&db_name';
END;
/
SET FEEDBACK on
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Obtain the MIN and MAX Snapshot IDs to be removed from the range of IDs |
prompt | order than &days_to_keep days. |
prompt +----------------------------------------------------------------------------+
SET FEEDBACK off
COLUMN lo_snap HEADING "Min Snapshot ID" NEW_VALUE LoSnapId
COLUMN hi_snap HEADING "Max Snapshot ID" NEW_VALUE HiSnapId
SELECT NVL(MAX(snap_id),0) hi_snap
, NVL(MIN(snap_id),0) lo_snap
FROM stats$snapshot
WHERE snap_time < (sysdate - &days_to_keep);
VARIABLE lo_snap NUMBER;
VARIABLE hi_snap NUMBER;
BEGIN
:lo_snap := &losnapid;
:hi_snap := &hisnapid;
END;
/
COLUMN l HEADING 'Low Snap ID'
COLUMN h HEADING 'High Snap ID'
SELECT
:lo_snap l
, :hi_snap h
FROM dual;
SET FEEDBACK ON
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Snapshots that will be removed for this database instance. |
prompt +----------------------------------------------------------------------------+
SET FEEDBACK off
COLUMN snap_id FORMAT 9999990 HEADING 'Snap Id'
COLUMN level FORMAT 99 HEADING 'Snap|Level'
COLUMN snap_date FORMAT a21 HEADING 'Snapshot Started'
COLUMN host_name FORMAT a15 HEADING 'Host'
COLUMN ucomment format a25 HEADING 'Comment'
SELECT
s.snap_id snap_id
, s.snap_level "level"
, to_char(s.snap_time,'mm/dd/yyyy HH24:MI:SS') snap_date
, di.host_name host_name
, s.ucomment ucomment
FROM
stats$snapshot s
, stats$database_instance di
WHERE
s.dbid = :dbid
AND di.dbid = :dbid
AND s.instance_number = :inst_num
AND di.instance_number = :inst_num
AND di.startup_time = s.startup_time
AND s.snap_id < :hi_snap
ORDER BY
db_name
, instance_name
, snap_id
/
SET HEADING off
SELECT 'WARNING: No snapshots found older than &days_to_keep days in STATS$SNAPSHOT'
FROM dual
WHERE NOT EXISTS
(
select null
from stats$snapshot
where instance_number = :inst_num
and dbid = :dbid
and snap_id = :lo_snap
)
OR
NOT EXISTS
(
select null
from stats$snapshot
where instance_number = :inst_num
and dbid = :dbid
and snap_id = :hi_snap
)
/
SET HEADING on
SET FEEDBACK ON
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Get begin and end snapshot times - these are used to delete undostat. |
prompt +----------------------------------------------------------------------------+
SET FEEDBACK OFF
COLUMN btime NEW_VALUE btime
COLUMN etime NEW_VALUE etime
SELECT
b.snap_id
, TO_CHAR(b.snap_time, 'YYYYMMDD HH24:MI:SS') btime
FROM
stats$snapshot b
WHERE
b.snap_id = :lo_snap
AND b.dbid = :dbid
AND b.instance_number = :inst_num;
SELECT
e.snap_id
, TO_CHAR(e.snap_time, 'YYYYMMDD HH24:MI:SS') etime
FROM stats$snapshot e
WHERE
e.snap_id = :hi_snap
AND e.dbid = :dbid
AND e.instance_number = :inst_num;
VARIABLE btime VARCHAR2(25);
VARIABLE etime VARCHAR2(25);
BEGIN
:btime := '&btime';
:etime := '&etime';
END;
/
SET FEEDBACK on
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Deleting snapshots older than &days_to_keep days.
prompt | Deleting snapshots &&losnapid - &&hisnapid.
prompt +----------------------------------------------------------------------------+
DELETE FROM stats$snapshot
WHERE instance_number = :inst_num
AND dbid = :dbid
AND snap_id between :lo_snap and :hi_snap;
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Delete any dangling SQLtext. The following statement deletes any dangling |
prompt | SQL statements which are no longer referred to by ANY snapshots. By |
prompt | default, Oracle comments this statement out as it can be very resource |
prompt | intensive. |
prompt +----------------------------------------------------------------------------+
SET FEEDBACK off
ALTER SESSION SET hash_area_size=1048576;
COLUMN last_snap_id HEADING 'Last Snap ID'
COLUMN count HEADING 'Count'
SELECT --+ index_ffs(st)
last_snap_id
, count(*) count
FROM
stats$sqltext st
WHERE
( hash_value
, text_subset
)
NOT IN
( select --+ hash_aj full(ss) no_expand
hash_value
, text_subset
from stats$sql_summary ss
where ( (
snap_id < :lo_snap
or
snap_id > :hi_snap
)
and dbid = :dbid
and instance_number = :inst_num
)
or
(
dbid != :dbid
or
instance_number != :inst_num
)
)
GROUP BY
last_snap_id;
SET FEEDBACK on
DELETE --+ index_ffs(st)
FROM stats$sqltext st
WHERE
( hash_value
, text_subset
)
NOT IN
( select --+ hash_aj full(ss) no_expand
hash_value
, text_subset
from stats$sql_summary ss
where ( (
snap_id < :lo_snap
or
snap_id > :hi_snap
)
and dbid = :dbid
and instance_number = :inst_num
)
or
(
dbid != :dbid
or
instance_number != :inst_num
)
);
SET FEEDBACK on
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | (OPTIONAL) - STATS$SEG_STAT_OBJ delete statement |
prompt +----------------------------------------------------------------------------+
DELETE --+ index_ffs(sso)
FROM stats$seg_stat_obj sso
WHERE ( dbid
, dataobj#
, obj#
)
NOT IN
(
select --+ hash_aj full(ss) no_expand
dbid
, dataobj#
, obj#
from
stats$seg_stat ss
where ( ( snap_id < :lo_snap
or
snap_id > :hi_snap
)
and dbid = :dbid
and instance_number = :inst_num
)
or
( dbid != :dbid
or
instance_number != :inst_num
)
);
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Delete from stats$undostat |
prompt | Undostat rows that cover the snap times |
prompt +----------------------------------------------------------------------------+
COLUMN dbid HEADING 'DB Id'
COLUMN instance_number HEADING 'Instance Number'
COLUMN snap_id HEADING 'Snap ID'
COLUMN begin_time HEADING 'Begin Time'
COLUMN end_time HEADING 'End Time'
SELECT
dbid
, instance_number
, snap_id
, TO_CHAR(begin_time, 'YYYYMMDD HH24:MI:SS') begin_time
, TO_CHAR(end_time, 'YYYYMMDD HH24:MI:SS') end_time
FROM
stats$undostat us
WHERE
dbid = :dbid
AND instance_number = :inst_num
AND end_time < to_date(:etime, 'YYYYMMDD HH24:MI:SS')
ORDER BY
snap_id;
DELETE from stats$undostat us
WHERE dbid = :dbid
AND instance_number = :inst_num
AND end_time < to_date(:etime, 'YYYYMMDD HH24:MI:SS');
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Delete from stats$database_instance |
prompt | Dangling database instance rows for that startup time |
prompt +----------------------------------------------------------------------------+
COLUMN dbid HEADING 'DB Id'
COLUMN instance_number HEADING 'Instance Number'
COLUMN startup_time HEADING 'Startup Time'
COLUMN snap_id HEADING 'Snap ID'
SELECT
dbid
, instance_number
, TO_CHAR(startup_time, 'DD-MON-YYYY HH24:MI:SS') startup_time
, snap_id
FROM
stats$database_instance di
WHERE
instance_number = :inst_num
AND dbid = :dbid
AND NOT EXISTS (select 1
from stats$snapshot s
where s.dbid = di.dbid
and s.instance_number = di.instance_number
and s.startup_time = di.startup_time)
ORDER BY
snap_id;
DELETE from stats$database_instance di
WHERE instance_number = :inst_num
AND dbid = :dbid
AND NOT EXISTS (select 1
from stats$snapshot s
where s.dbid = di.dbid
and s.instance_number = di.instance_number
and s.startup_time = di.startup_time);
prompt
prompt
prompt
prompt +----------------------------------------------------------------------------+
prompt | Delete from stats$statspack_parameter |
prompt | Dangling statspack parameter rows for the database / instance |
prompt +----------------------------------------------------------------------------+
COLUMN dbid HEADING 'DB Id'
COLUMN instance_number HEADING 'Instance Number'
COLUMN session_id HEADING 'Session ID'
COLUMN snap_level HEADING 'Snap Level'
SELECT
dbid
, instance_number
, session_id
, snap_level
FROM
stats$statspack_parameter sp
WHERE
instance_number = :inst_num
AND dbid = :dbid
AND NOT EXISTS (select 1
from stats$snapshot s
where s.dbid = sp.dbid
and s.instance_number = sp.instance_number);
DELETE from stats$statspack_parameter sp
WHERE instance_number = :inst_num
AND dbid = :dbid
AND NOT EXISTS (select 1
from stats$snapshot s
where s.dbid = sp.dbid
and s.instance_number = sp.instance_number);
SPOOL off
COMMIT;
EXIT