Decode360's Blog

业精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

  BlogJava :: 首页 :: 新随笔 :: 联系 ::  :: 管理 ::
  397 随笔 :: 33 文章 :: 29 评论 :: 0 Trackbacks
管理可恢复空间
 
    学了半天都不知道这个内容到底讲得是什么意思?Oracle有可恢复空间这个概念吗?实在是不理解……
 
一、可恢复空间分配的概述
 
1、可恢复语句如何工作:
 
    ① 客户使用ALTER SESSION语句明确启用可恢复时才可以执行恢复
 
    ② 以下情况下,可恢复语句被暂停:
        * 没有空间条件
        * 达到最大盘区条件
        * 超过空间限额条件
 
    ③ 可恢复语句执行被暂停期间,采用以下动作:
        * 修改日志中报告错误
        * 若在AFTER SUSPEND系统事件上注册触发器,则触发器执行
          (使用DBMS_RESUMABLE包和DBA_RESUMABLE视图访问错误信息数据)
 
    ④ 暂停一个语句自动导致暂停该事务。(暂停到恢复期间所有事务资源被保持)
 
    ⑤ 出错条件消失时,暂停语句自动恢复执行
 
    ⑥ 使用DBMS_RESUMABLE.ABORT()过程,可强制暂停语句发出异常
 
    ⑦ 暂停超过时间间隔与可恢复语句相关联(例如超过2小时的可恢复语句被唤醒并报错)
 
    ⑧ 可恢复语句在执行期间可被多次暂停和恢复。
 
    注:可恢复方式不支持远程操作。
 
2、可恢复的操作
 
    ① 查询:
        用到临时空间(排序区)的SELECT语句是可恢复的。
        当使用OCI时OCIStmtExecute()和OCIStmtFetch()调用是可恢复的。
 
    ② DML:
        包括INSERT、UPDATE、DELETE,以及来自外部表的INSERT ONTO ... SELECT
        与执行它们的接口无关,可以是OCI、JSQL、PL/SQL或其他接口
 
    ③ 导入/导出
        SQL*Loader的命令行出现可更改错误之后是可恢复的
 
    ④ DDL:以下语句是可恢复的:
        ① CREATE TABLE ... AS SELECT
        ② CREATE INDEX
        ③ ALTER INDEX ... REBUILD
        ④ ALTER TABLE ... MOVE PARTITION
        ⑤ ALTER TABLE ... SPLIT PARTITION
        ⑥ ALTER INDEX ... REBUILD PARTITION
        ⑦ ALTER INDEX ... SPLIT PARTITION
        ⑧ CREATE MATERIALIZED VIEW
        ⑨ CREATE MATERIALIZED VIEW LOG
 
3、哪些错误是可改正的
 
    ① 没有空间条件
    ② 达到最大盘区条件
    ③ 超过空间限额条件
 
4、字典管理的表空间可恢复空间分配的限制
 
    ① CREATE TABLE 或 CREATE INDEX这样的DDL操作执行时,使用了MAXEXTENTS参数,会导致空间用完的情况。此时操作不会被暂停,而是被放弃。因为在初期创建的时候无法进行修改。而如果是DML操作增加或修改了MAXEXTENTS参数,则会被暂停并在以后恢复。注意可以使用MAXEXTENTS UNLIMITED或使用本地管理的表空间来克服。
 
    ② 回滚段位于字典管理的表空间中时,对回滚段的空间分配是不可恢复的。但是对于用户对象的空间按分配仍然可恢复。要克服这种限制,建议使用自动撤销管理或将回滚段放置在本地管理的表空间中。
 
 
二、启用和禁用可恢复空间分配
 
1、语句格式:
 
    ALTER SESSION ENABLE RESUMABLE; --启用
    ALTER SESSION DISABLE RESUMABLE; --禁用
 
2、指定超时间隔
 
    超时间隔表示超过该间隔时间如果没有采取干预,暂停语句会出错。
 
    ① 一种方法是使用SQL语句来进行修改:
 
    ALTER SESSION ENABLE RESUMABLE TIMEOUT 3600; --默认7200秒
 
    ② 另一种方法可以用触发器来设置,如:
 
    CREATE OR REPLACE TRIGGER resumable_default_timeout
    AFTER SUSPEND
    ON DATABASE
    BEGIN
    DBMS_RESUMABLE.SET_TIMEOUT(3600);
    END;
 
3、可恢复语句命名
 
    ALTER SESSION ENABLE RESUMABLE TIMEOUT 3600 NAME 'insert into table';
 
    NAME的默认值是:User USERNAME(USERID), Session SESSIONID, Instance INSTANCEID
    NAME用于在DBA_RESUMABLE和USER_RESUMABLE视图中标识该可恢复语句
 
 
三、检测暂停的语句
 
    因为可恢复语句被暂停时,客户端并不会报错,为了采取纠正动作,需要检测暂停语句。
 
    1、AFTER SUSPEND系统事件和触发器
 
    在AFTER SUSPEND触发器中,可以使用USER_RESUMABLE或DBA_RESUMABLE视图,或者DBMS_RESUMABLE.SPACE_ERROR_INFO函数来获取关于可恢复语句的信息,以及用来放弃暂停的语句或调节可恢复超时间隔的值。
 
    2、在视图中查看
 
    DBA_RESUMABLE:包含当前正在执行或被暂停的可恢复语句的行。
    V$SESSION_WAIT:语句被暂停即进入等待状态,选择EVENT值为“susprended on space error”的行。
 
    3、DBMS_RESUMABLE包介绍
 
    ① ABORT(sessionID):
        放弃一个暂停的可恢复语句。sessionID是该语句在其执行的会话的标识。对于并行的DML/DDL,则取任何一个sessionID。
        可以在AFTER SUSPEND触发器内调用,也可以在触发器外调用。
 
    ② GET_SESSION_TIME3OUT(sessionID):
        为使用sessionID的会话返回可恢复语句的当前超时间隔,单位秒。会话不存在时返回-1。
 
    ③ SET_SESSION_TIMEOUT(sessionID,timeout):
        为sessionID设置超时间隔,会话不存在时则不做任何动作。
 
    ④ GET_TIMEOUT():
        返回当前会话的可恢复语句当前超时间隔值。
 
    ⑤ SET_TIMEOUT(timeout):
        为当前会话的可恢复语句设置一个超时间隔。
 
 
四、可恢复空间分配的例子
 
    建立一个触发器,其有以下两个作用:
 
    1、如果回滚段达到它的空间限额,那么一条消息发给DBA且该语句被放弃
    2、如果任何其他的可改正错误发生,超时间隔被重置为8小时
 

CREATE OR REPLACE TRIGGER resumable_default

  AFTER SUSPEND ON DATABASE

DECLARE

  /* declare transaction in this trigger is autonomous */

  /* this is not required because transactions within a trigger are always autonomous */

  PRAGMA AUTONOMOUS_TRANSACTION ;

  cur_sid         NUMBER ;

  cur_inst        NUMBER ;

  errno           NUMBER ;

  err_type        VARCHAR2 ;

  object_owner    VARCHAR2 ;

  object_type     VARCHAR2 ;

  table_space     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

  ret_value := DBMS_RESUMABLE.SPACE_ERROR_INFO(err_type,

                                               object_type,

                                               object_owner,

                                               table_space_name,

                                               object_name,

                                               sub_object_name);

  /*

  -- If the error is related to rollback segment, log error, send email

  -- to DBA, and abort the segment. Otherwise, set timeout to a8 hours.

  --

  -- sys.rbs_error is created by DBA manually and defined as

  -- sql_text VARCHAR2(1000), error_msg VARCHAR2(4000),

  -- suspend_time DATE

  */

  IF OBJECT_TYPE = 'ROLLBACK 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 INSRANCE_ID = cur_inst;

    -- Send email to receipient via UTL_SMTP package

    msg_body  := 'Subject: Space Error Occurred

Space limit reached for rollback 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, 'sender@localhost' );

    UTL_SMTP.RCPT(mail_conn, 'recipient@localhost' );

    UTL_SMTP.DATA(mail_conn, msg_body);

    UTL_SMTP.QUIT(mail_conn);

    -- Abort the segment

    DBMS_RESUMABLE.ABORT(cur_sid);

  ELSE

    -- Set timeout to 8 hours

    DBMS_RESUMABLE.SET_TIMEOUT( 28800 );

  END IF ;

  /* commit autonomous transaction */

  COMMIT ;

END ;

 

 
 
 
posted on 2009-02-09 22:15 decode360 阅读(98) 评论(0)  编辑  收藏 所属分类: 08.DBA

只有注册用户登录后才能发表评论。


网站导航: