In the followingexample, a system wide AFTER SUSPEND trigger is created andregistered as user SYS at the database level. Whenever a resumablestatement is suspended in any session, this trigger can have either of twoeffects:
1)If an undosegment has reached its space limit, then a message is sent to the DBA and the statement is aborted.
2)If any otherrecoverable error has occurred, the timeout interval is reset to 8 hours.
Here are the statementsfor this example:
-- Hundsun@Askerain
--If the error is related to undo segments, log error, send email
--to DBA, and abort the statement. Otherwise, set timeout to 8 hours.
--
--sys.rbs_error is a table which is to be
--created by a DBA manually and defined as
--(sql_text VARCHAR2(1000), error_msg VARCHAR2(4000),
--suspend_time DATE)
-- drop table sys.rbs_error avoid corruption
DROP TABLE sys.rbs_error;
-- create table sys.rbs_error to record resumable error information
CREATE TABLE sys.rbs_error(sql_text VARCHAR2(1000),error_msg VARCHAR2(4000),suspend_time DATE);
-- create a trigger to set strategies and report error information
CREATE OR REPLACE TRIGGER resumable_space_trigger
AFTER SUSPEND ON DATABASE
-- declare transaction in this trigger is autonomous
-- this is not required because transactions within a trigger are always autonomous
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
cur_sid NUMBER;
cur_inst NUMBER;
errno NUMBER;
err_type VARCHAR2;
object_owner VARCHAR2;
object_type VARCHAR2;
table_space_name VARCHAR2;
object_name VARCHAR2;
sub_object_name VARCHAR2;
error_txt VARCHAR2;
msg_body VARCHAR2;
ret_value BOOLEAN;
mail_conn UTL_SMTP.CONNECTION;
BEGIN
--Get session ID
SELECT DISTINCT (SID) INTO cur_SID FROM V$MYSTAT;
--Get instance number
cur_inst := userenv('instance');
--Get space error information
ret_value := DBMS_RESUMABLE.SPACE_ERROR_INFO(err_type,object_type,object_owner,
table_space_name,object_name,sub_object_name);
IF OBJECT_TYPE = 'UNDO SEGMENT' THEN /* LOG ERROR */
INSERT INTO sys.rbs_error(SELECT SQL_TEXT, ERROR_MSG, SUSPEND_TIME
FROM DBMS_RESUMABLE WHERE SESSION_ID = cur_sid AND INSTANCE_ID = cur_inst);
SELECT ERROR_MSG INTO error_txt FROM DBMS_RESUMABLE
WHERE SESSION_ID = cur_sid and INSTANCE_ID = cur_inst;
-- Send email to receipient through UTL_SMTP package
msg_body := 'Subject: Space Error Occurred Space limit reached for undo segment'||object_name ||'on'||
TO_CHAR(SYSDATE,' Month dd, YYYY, HH :MIam')||'. Error message was '||error_txt;
mail_conn := UTL_SMTP.OPEN_CONNECTION('localhost', 25);
UTL_SMTP.HELO(mail_conn, 'localhost');
UTL_SMTP.MAIL(mail_conn, 'oracle@localhost');
UTL_SMTP.RCPT(mail_conn, 'oracle@localhost');
UTL_SMTP.DATA(mail_conn, msg_body);
UTL_SMTP.QUIT(mail_conn);
-- Abort the statement
DBMS_RESUMABLE.ABORT(cur_sid);
ELSE
-- Set timeout to 8 hours
DBMS_RESUMABLE.SET_TIMEOUT(28800);
END IF;
/* commit autonomous transaction */
COMMIT;
END;
/