下面的 script可以利用cron排程来自动执行清除超过保留数目的旧有snapshot资料,这个script不需要知道PERFSTAT此帐号的密码就可执行,并已经经由Oracle8.1.7和9.2.0上测试过。
步骤:
1)储存这个script取名为sp_purge.ksh在Unix主机上。
2)注意你的系统上tmp目录是否存在,如果你不想所有产生的log写到/tmp去,你必须去更改script。
3)如果你的oratab这个目录位置不是在/var/opt/oracle,你就必须手动去更新script来配合你的环境。
4)设定可执行权限给script: chmod u+x sp_purge.ksh
5)设定cron job来执行这个script。执行这个script需要三个参数:
要清除 snapshot的资料库名称。
要保留的 snapshot数量。
执行后要寄发电子邮件的对象。
00 19 * * 1-5 /scripts/sp_purge.ksh prod 60 mrogers@company.com /tmp/sp_purge_portal.log 2&1 &
这个范例是说:星期一到星期五每天晚上七点执行此 script,针对 'prod' 这个资料库只保留最近的60个snapshots纪录,多余的则清除,并且寄发讯息给 mrogers@company.com 。
6)注意这个 script应该配合指定的instance一起执行,如果这台主机上并没有这个script所指定的instance在执行中,一个简单的讯息可在tmp目录下找到。
*** ERROR: The ORACLE_SID specified in parameter 1 is not a valid SID.
(Note that the SID is case sensitive.)
7)所有产生的执行纪录都可以在/tmp下找到。
#!/bin/ksh
# Script Name: sp_purge.ksh
# This script is designed to purge StatsPack snapshots.
#
# Parameter $1 is the name of the database.
# Parameter $2 is the maximum number of snapshots to retain.
# Parameter $3 is the mail recipient for success messages.
#
# To succeed, this script must be run on the machine on which the
# instance is running.
# Example for calling this script:
#
# sp_purge.ksh prod 30 username@mycompany.com
# Script History:
#
# Who Date Action
# --------------- ------------ --------------------------------------------
# Mark J. Rogers 22-Sep-2003 Script creation.
#
#
#
tmp_dir=/tmp
# Validate the parameters.
if [[ $# -ne 3 ]]; then
echo ""
echo "*** ERROR: You must specify these parameters: "
echo ""
echo " 1: the name of the database"
echo " 2: the maximum # of snapshots to retain"
echo " 3: the mail recipient for success messages"
echo ""
exit 1
fi
grep "^${1}:" /var/opt/oracle/oratab /dev/null
if [[ $? -ne 0 ]]; then
echo ""
echo "*** ERROR: The ORACLE_SID specified in parameter 1 is not a valid SID."
echo " (Note that the SID is case sensitive.)"
echo ""
exit 1
fi
if [[ ! (${2} -ge 0) ]]; then
echo ""
echo "*** ERROR: Parameter 2 must specify the # of snapshots to retain."
echo ""
exit 1
fi
# Ensure that the instance is running on the current machine.
ps -ef | grep pmon | grep $1 /dev/null
if [[ $? -ne 0 ]]; then
echo ""
echo "*** ERROR: Instance $1 is not running on machine `uname -n` "
echo " on `date`."
echo " The instance must be running on the current machine for this"
echo " script to function properly."
echo ""
echo " Exiting..."
echo ""
exit 1
fi
# Establish error handling for this UNIX script.
function errtrap {
the_status=$?
echo ""
echo " *** ERROR: Error message $the_status occured on line number $1."
echo ""
echo " *** The script is aborting."
echo ""
exit $the_status
}
trap
'
errtrap $LINENO
'
ERR
# Set up the Oracle environment.
export ORACLE_SID=${1}
export ORAENV_ASK=NO
. oraenv
script_name=${0##*/}
echo ""
echo "Script: $script_name"
echo " started on: `date`"
echo " by user: `id`"
echo " on machine: `uname -n`"
echo ""
echo "This script is designed to purge StatsPack snapshots for the "
echo " $ORACLE_SID database."
echo ""
echo "You have requested to retain no more than $2 StatsPack snapshots."
echo ""
tmp_script=${tmp_dir}/sp_purge_tmp_$ORACLE_SID.ksh # script to actually purge
tmp_output=${tmp_dir}/sp_purge_tmp_$ORACLE_SID.out # output to be mailed
rm -f $tmp_script
rm -f $tmp_output
sqlplus -s <<EOF_SP<br // as sysdba
whenever sqlerror exit failure rollback
whenever oserror exit failure rollback
SET SERVEROUTPUT ON
SET FEEDBACK OFF
VARIABLE P_SNAPS_TO_RETAIN NUMBER
VARIABLE P_LOSNAPID NUMBER
VARIABLE P_HISNAPID NUMBER
BEGIN
/* Assign values to these variables. */
:P_SNAPS_TO_RETAIN := ${2};
:P_LOSNAPID := -1;
:P_HISNAPID := -1;
END;
/
-- Identify the snapshot ids to purge, if any.
DECLARE
V_LOSNAPID NUMBER := NULL; -- Low snapshot ID to purge.
V_HISNAPID NUMBER := NULL; -- High snapshot ID to purge.
V_COUNT NUMBER := NULL; -- Number of snapshots current saved.
V_COUNTER NUMBER := 0; -- Temporary counter variable.
V_DBID NUMBER := NULL; -- Current database ID.
V_INSTANCE_NUMBER NUMBER := NULL; -- Current instance number.
V_SNAPS_TO_RETAIN NUMBER := :P_SNAPS_TO_RETAIN; -- Max snaps to retain.
BEGIN
select
d.dbid,
i.instance_number
INTO
v_DBID,
V_INSTANCE_NUMBER
from
v$database d,
v$instance i;
select
count(snap_id)
into
v_count
from
perfstat.stats$snapshot
where
dbid = V_DBID AND
instance_number = V_INSTANCE_NUMBER;
IF V_COUNT <= V_SNAPS_TO_RETAIN THEN
-- We do NOT need to perform a purge.
DBMS_OUTPUT.PUT_LINE ('NOTE: There are only ' ||
to_char(v_count) || ' snapshots currently saved.');
ELSE
-- We DO need to perform a purge.
DBMS_OUTPUT.PUT_LINE ('There are currently ' ||
to_char(v_count) || ' snapshots saved.');
-- Obtain the low snapshot id to be purged.
select
min(snap_id)
into
V_LOSNAPID
from
perfstat.stats$snapshot
where
dbid = V_DBID AND
instance_number = V_INSTANCE_NUMBER;
-- Obtain the high snapshot id to be purged.
FOR V_HISNAPID_REC IN
(SELECT
SNAP_ID
FROM
perfstat.stats$snapshot
WHERE
dbid = V_DBID AND
instance_number = V_INSTANCE_NUMBER
ORDER BY
SNAP_ID DESC)
LOOP
V_COUNTER := V_COUNTER + 1;
IF V_COUNTER V_SNAPS_TO_RETAIN THEN
V_HISNAPID := V_HISNAPID_REC.SNAP_ID;
EXIT; -- Exit this LOOP and proceed to the next statement.
END IF;
END LOOP;
:P_LOSNAPID := V_LOSNAPID;
:P_HISNAPID := V_HISNAPID;
END IF;
END;
/
prompt
-- Generate the specific purge script.
set linesize 60
spool $tmp_script
begin
IF (:P_LOSNAPID < -1) THEN
/* Build the script to purge the StatsPack snapshots. */
dbms_output.put_line('#!/bin/ksh');
dbms_output.put_line('#THIS IS THE SCRIPT TO ACTUALLY PERFORM THE PURGE');
dbms_output.put_line('trap '' exit $? '' ERR');
dbms_output.put_line('sqlplus -s << SP_EOF2');
dbms_output.put_line('/ as sysdba');
dbms_output.put_line('whenever sqlerror exit failure rollback');
dbms_output.put_line('whenever oserror exit failure rollback');
dbms_output.put_line('@ $ORACLE_HOME/rdbms/admin/sppurge.sql');
dbms_output.put_line(:P_LOSNAPID);
dbms_output.put_line(:P_HISNAPID);
dbms_output.put_line('-- the following are needed again');
dbms_output.put_line('whenever sqlerror exit failure rollback');
dbms_output.put_line('whenever oserror exit failure rollback');
dbms_output.put_line('commit;');
dbms_output.put_line('exit');
dbms_output.put_line('SP_EOF2');
dbms_output.put_line('exit $?');
END IF;
end;
/
spool off
exit
EOF_SP
if [[ ! (-f ${tmp_script}) ]]; then
echo ""
echo "*** ERROR: Temporary script: ${tmp_script} does not exist."
echo ""
exit 1
fi
if [[ `cat ${tmp_script} | wc -l` -ne 0 ]]; then
# Execute the newly generated StatsPack snapshot purge script.
chmod u+x $tmp_script
echo ""
echo "Performing the purge..."
echo ""
$tmp_script $tmp_output
cat $tmp_output # display the output
# Check the output file for a success message:
trap ' ' ERR # temporarily reset error handling for the grep command
grep "^Purge of specified Snapshot range complete." $tmp_output /dev/null
if [[ $? -ne 0 ]]; then
echo ""
echo "*** ERROR: The purge did not complete successfully."
echo " Check the log file $tmp_output."
echo ""
exit 1
fi
trap ' errtrap $LINENO ' ERR # re-establish desired error handler
else
# No purge script was created.
echo "No snapshot purge was necessary." $tmp_output
fi
echo ""
echo "The ${script_name} script appears to have completed "
echo " successfully on `date`."
echo ""
mailx
-s "sp_purge.ksh in $ORACLE_SID on `uname -n` completed successfully"
${3}
< $tmp_output
# End of script sp_purge.ksh.