478 lines
14 KiB
SQL
478 lines
14 KiB
SQL
-- +----------------------------------------------------------------------------+
|
|
-- | Jeffrey M. Hunter |
|
|
-- | jhunter@idevelopment.info |
|
|
-- | www.idevelopment.info |
|
|
-- |----------------------------------------------------------------------------|
|
|
-- | Copyright (c) 1998-2012 Jeffrey M. Hunter. All rights reserved. |
|
|
-- |----------------------------------------------------------------------------|
|
|
-- | DATABASE : Oracle |
|
|
-- | FILE : sp_purge_n_days_9i.sql |
|
|
-- | CLASS : Statspack |
|
|
-- | PURPOSE : This script is responsible for removing all Statspack snapshot |
|
|
-- | records older than [n] 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 will either prompt for the number of days |
|
|
-- | or this parameter can be passed in from another calling |
|
|
-- | program. |
|
|
-- | |
|
|
-- | 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=&1
|
|
|
|
UNDEFINE dbid inst_num hisnapid
|
|
|
|
WHENEVER SQLERROR EXIT ROLLBACK
|
|
|
|
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);
|
|
|
|
|
|
COMMIT;
|
|
|
|
EXIT
|
|
|
|
|