ORACLE 12.2新特性-在线重定义新增功能

1. 监视表在线重定义进度

   可以查询V$ONLINE_REDEF视图以监视联机表重定义操作的进度。

   select * from V$ONLINE_REDEF;

   该V$ONLINE_REDEF视图为该PROGRESS列中的操作提供了百分比完成值。该视图在该OPERATION列中显示完成该操作所需的步骤总数。例如,如果操作中有10个步骤,则此列可能显示Step 6 out of 10。该视图还包括SUBOPERATION列和DETAILED_MESSAGE列,用用于提供有关当前操作的更详细的信息。

2. 失败后重新启动表在线重新定义

    如果联机表重新定义失败,则可以完成以下步骤来重新启动它:

  1. 查询DBA_REDEFINITION_STATUS视图以确定故障原因以及纠正该故障所需的操作。
    例如,运行以下查询:
    SELECT BASE_TABLE_NAME, 
           INTERIM_OBJECT_NAME, 
           OPERATION, 
           STATUS, 
           RESTARTABLE, 
           ACTION 
       FROM DBA_REDEFINITION_STATUS;
    如果 RESTARTABLE值为 Y,则可以重新开始操作。如果 RESTARTABLE值为 N,则无法重新开始操作,必须从头开始重新定义。
  2. 执行上一步查询结果中指定的操作。
  3. 使用查询结果中指定的操作重新启动联机重新定义,然后运行所有后续操作以完成表的联机重新定义。

示例-- SYNC_INTERIM_TABLE过程调用失败

本示例说明了重新启动在线重新定义操作,该操作在SYNC_INTERIM_TABLE过程调用中失败,并出现以下错误:
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE('U1', 'ORIG', 'INT');
END;
/
ORA-42009: error occurred while synchronizing the redefinition
ORA-01653: unable to extend table U1.INT by 8 in tablespace my_tbs
ORA-06512: at "SYS.DBMS_REDEFINITION", line 148
ORA-06512: at "SYS.DBMS_REDEFINITION", line 2807
ORA-06512: at line 2
  1. 查询DBA_REDEFINITION_STATUS视图:

    SELECT BASE_TABLE_NAME,  INT_TABLE_NAME, OPERATION, STATUS, RESTARTABLE, ACTION 
       FROM DBA_REDEFINITION_STATUS;
    
    BASE_TABLE_NAME INT_OBJ_NAME OPERATION          STATUS  RESTARTABLE ACTION
    --------------- ------------ ------------------ ------- ----------- ---------
    ORIG            INT          SYNC_INTERIM_TABLE FAILED  Y           Fix error

    因为查询结果RESTARTABLEY,在线重定义操作可以重新开始。要重新启动操作,请更正操作失败时返回的错误,然后重新启动操作。在此示例中,错误为“ ORA-01653: unable to extend table U1.INT by 8 in tablespace my_tbs”。

  2. 通过向表空间my_tbs添加数据文件来增加表空间的大小:
    ALTER TABLESPACE my_tbs
       ADD DATAFILE '/u02/oracle/data/my_tbs2.dbf' SIZE 100M;
  3. 重新运行SYNC_INTERIM_TABLE过程调用:

    BEGIN
       DBMS_REDEFINITION.SYNC_INTERIM_TABLE('U1', 'ORIG', 'INT');
    END;
    /

示例--物化视图日志问题

在原始表上开始重新定义之后,物化视图日志可能会出现问题。例如,由于某些原因,物化视图日志可能被意外删除或损坏。在这种情况下,将返回类似于以下内容的错误:

ERROR at line 1:
ORA-42010: error occurred while synchronizing the redefinition
ORA-12034: materialized view log on "HR"."T1" younger than last refresh

假设正在重新定义使用以下SQL语句创建的表:

CREATE TABLE hr.t1(
      c1 NUMBER PRIMARY KEY, 
      c2 NUMBER)
   TABLESPACE example_tbs;

假设使用以下SQL语句创建了一个临时表,该语句更改了表的表空间:

CREATE TABLE hr.int_t1(
      c1 NUMBER PRIMARY KEY, 
      c2 NUMBER)
   TABLESPACE hr_tbs;
  1.  

  2. 开始重新定义过程。

    BEGIN 
      DBMS_REDEFINITION.START_REDEF_TABLE(
        uname =>'hr',
        orig_table =>'t1',
        int_table =>'int_t1'); 
    end; 
    /
    
  3. Drop the materialized view log on the original table

    DROP MATERIALIZED VIEW LOG ON hr.t1;
  4. Create a new materialized view log on the original table.

    CREATE MATERIALIZED VIEW LOG ON hr.t1 
       WITH COMMIT SCN PURGE
       IMMEDIATE ASYNCHRONOUS;
  5. Synchronize the interim table hr.int_t1.

    BEGIN 
      DBMS_REDEFINITION.SYNC_INTERIM_TABLE(
        uname      => 'hr', 
        orig_table => 't1',
        int_table  => 'int_t1');
    END;
    /
    BEGIN
    *
    ERROR at line 1:
    ORA-42010: error occurred while synchronizing the redefinition
    ORA-12034: materialized view log on "HR"."T1" younger than last refresh
    
  6. 由于返回了错误,请检查DBA_REDEFINITION_STATUS视图。

    COLUMN BASE_OBJECT_NAME FORMAT A11
    COLUMN OPERATION FORMAT A10
    COLUMN STATUS FORMAT A10
    COLUMN RESTARTABLE FORMAT A11
    COLUMN ERR_TXT FORMAT A15
    COLUMN ACTION FORMAT A18
    
    SELECT BASE_OBJECT_NAME, OPERATION, STATUS, RESTARTABLE, ERR_TXT, ACTION 
       FROM DBA_REDEFINITION_STATUS 
       ORDER BY BASE_TABLE_NAME, BASE_OBJECT_NAME;
    
    
    BASE_OBJECT OPERATION  STATUS     RESTARTABLE ERR_TXT         ACTION
    ----------- ---------- ---------- ----------- --------------- ------------------
    T1          SYNC_REDEF Failure    N           ORA-12034: mate Abort redefinition
                _TABLE                            rialized view l
                                                  og on "HR"."T1"
                                                   younger than l
                                                  ast refresh
    

    由于查询结果中存在联机重新定义操作,因此无法重新启动RESTARTABLEN,并且该ACTION列指示必须放弃联机表重新定义操作。

  7. Abort the online table redefinition operation

    BEGIN 
      DBMS_REDEFINITION.ABORT_REDEF_TABLE(
        uname      => 'hr', 
        orig_table => 't1',
        int_table  => 'int_t1');
    END;
    /

3. 表在线重定义回滚

    1. 关于回滚表在线重定义

    在线重定义表之后,可以将表回滚到其在线重定义之前,同时保留对表所做的所有数据操作语言(DML)更改。

    在某些情况下,您可能需要撤消在线重定义表的操作。例如,重定义之后,表上的操作性能可能比重定义之前要差。在这些情况下,你可以将表回滚到其原始定义,同时保留重定义表后对该表所做的所有DML更改。表在线重定义回滚主要用于重定义更改表的存储特性,并且更改意外导致性能降低的情况。

    要启用表在线重定义的回滚,必须在DBMS_REDEFINITION.START_TABLE_REDEF过程中将ENABLE_ROLLBACK参数设置为TRUE。如果将此参数设置为true,则Oracle数据库将在重定义完成后维护在重定义期间创建的临时表。您可以运行该SYNC_INTERIM_TABLE过程以定期同步临时表,以便将对重定义的表所做的DML更改应用于临时表。内部的物化视图和物化视图日志可以维护临时表。如果您决定回滚表在线重定义,则会同步临时表,并且Oracle数据库将切换回该表,以便该表具有其原始定义。

   以下限制适用于表在线重定义回滚:

   当原始表的列到临时表的列没有一对一映射时,在重定义期间列映射中不能有运算符或函数。

   当原始表的列到临时表的列有一对一的映射时,列映射中可以有运算符和函数。

   当为重定义启用回滚时,在回滚或中止在表在线重定义之前,不能再次重定义该表。

   2. 执行表在线重定义回滚

   DBMS_REDEFINITION包中的ROLLBACK过程返回一个在保留DML更改的同时在线重新定义为其原始定义的表。

   要使用此ROLLBACK过程,必须在表在线重定义期间启用表在线重定义回滚。如果决定保留表在线重定义所做的更改,则可以运行ABORT_ROLLBACK过程。

  1. 执行表在线重定义,从START_REDEF_TABLE过程开始,到FINISH_REDEF_TABLE完成过程结束。START_REDEF_TABLE过程ENABLE_ROLLBACK参数必须设置为TRUE。此参数的默认值为FALSE
  2. 可选:定期运行该SYNC_INTERIM_TABLE过程,以便将对重定义的表进行的DML更改应用于临时表。
    如果定期将DML更改应用到临时表,则可以提高表在线重定义回滚的性能。
  3. 选择以下选项之一:
    • 如果要回滚表重新定义所做的更改并返回到原始表定义,请在DBMS_REDEFINITION包中运行ROLLBACK过程。
    • 如果要保留表在线重定义所做的更改,请在DBMS_REDEFINITION包运行ABORT_ROLLBACK程序。

      中止rollback将停止维护临时表,并删除启用回滚的实例化视图和实例化日志。

示例--回滚表在线重定义

本示例说明了通过更改表的存储特征来在线重新定义表。具体而言,此示例在表在线重新定义期间压缩表的表空间。假设您要在完成在线重新定义后评估表的性能。如果表的性能不及预期,那么您希望能够回滚在线重新定义所做的更改。

Assume that the following statements created the original tablespace and table:

CREATE TABLESPACE tst_rollback_tbs 
   DATAFILE 'tst_rollback_tbs.dbf' SIZE 10M 
   ONLINE; 

CREATE TABLE hr.tst_rollback
    (rllbck_id    NUMBER(6) PRIMARY KEY,
     rllbck_name  VARCHAR2(20)) 
   TABLESPACE tst_rollback_tbs
   STORAGE (INITIAL 2M);
  1. In SQL*Plus, connect as a user with the required privileges for performing online redefinition of a table.

    Specifically, the user must have the privileges described in "Privileges Required for the DBMS_REDEFINITION Package".

    See "Connecting to the Database with SQL*Plus".

  2. Create a compressed tablespace for the interim table.

    CREATE TABLESPACE tst_cmp_rollback_tbs 
       DEFAULT ROW STORE COMPRESS ADVANCED
       DATAFILE 'tst_cmp_rollback_tbs.dbf' SIZE 10M 
       ONLINE; 
  3. Create an interim table hr.int_tst_rollback.

    CREATE TABLE hr.int_tst_rollback
        (rllbck_id    NUMBER(6) PRIMARY KEY,
         rllbck_name  VARCHAR2(20)) 
       TABLESPACE tst_cmp_rollback_tbs
       STORAGE (INITIAL 2M);

    Ensure that the interim table uses the compressed tablespace created in the previous step.

  4. Start the redefinition process.

    BEGIN
      DBMS_REDEFINITION.START_REDEF_TABLE(
        uname           => 'hr', 
        orig_table      => 'tst_rollback',
        int_table       => 'int_tst_rollback',
        options_flag    => DBMS_REDEFINITION.CONS_USE_PK,
        enable_rollback => TRUE);
    END;
    /
    

    Ensure that enable_rollback is set to TRUE so that the changes made by online redefinition can be rolled back.

  5. Copy dependent objects.

    DECLARE
    num_errors PLS_INTEGER;
    BEGIN
      DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(
        uname            => 'hr', 
        orig_table       => 'tst_rollback',
        int_table        => 'int_tst_rollback',
        copy_indexes     => DBMS_REDEFINITION.CONS_ORIG_PARAMS, 
        copy_triggers    => TRUE, 
        copy_constraints => TRUE, 
        copy_privileges  => TRUE, 
        ignore_errors    => TRUE, 
        num_errors       => num_errors);
    END;
    /
    
  6. Query the DBA_REDEFINITION_ERRORS view to check for errors.

    SET LONG  8000
    SET PAGES 8000
    COLUMN OBJECT_NAME HEADING 'Object Name' FORMAT A20
    COLUMN BASE_TABLE_NAME HEADING 'Base Table Name' FORMAT A10
    COLUMN DDL_TXT HEADING 'DDL That Caused Error' FORMAT A40
     
    SELECT OBJECT_NAME, BASE_TABLE_NAME, DDL_TXT FROM 
             DBA_REDEFINITION_ERRORS;
    

    You can ignore errors related to the primary key and indexes.

  7. Synchronize the interim table hr.int_tst_rollback.

    BEGIN 
      DBMS_REDEFINITION.SYNC_INTERIM_TABLE(
        uname      => 'hr', 
        orig_table => 'tst_rollback',
        int_table  => 'int_tst_rollback');
    END;
    /
    
  8. Complete the redefinition.

    BEGIN
      DBMS_REDEFINITION.FINISH_REDEF_TABLE(
        uname      => 'hr', 
        orig_table => 'tst_rollback',
        int_table  => 'int_tst_rollback');
    END;
    /
    

    The table hr.tst_rollbck is locked in the exclusive mode only for a small window toward the end of this step. After this call the table hr.tst_rollback is redefined such that it has all the attributes of the hr.int_tst_rollback table. In this example, the tablespace for the hr.tst_rollbck table is now compressed.

  9. During the evaluation period, you can periodically synchronize the interim table hr.int_tst_rollback.

    BEGIN 
      DBMS_REDEFINITION.SYNC_INTERIM_TABLE(
        uname      => 'hr', 
        orig_table => 'tst_rollback',
        int_table  => 'int_tst_rollback');
    END;
    /
    

    Synchronizing the tables updates the original table with the DML changes made to the redefined table. When you synchronize the tables periodically, a rollback operation is more efficient because fewer DML changes must be made to the original table. You can query the STATUS column of the DBA_REDEFINITION_STATUS view to determine the status of the rollback operation.

  10. Perform one of the following actions:

    • Assume that the redefined table did not perform as well as expected, and roll back the changes made by online redefinition.
      BEGIN 
        DBMS_REDEFINITION.ROLLBACK(
          uname      => 'hr', 
          orig_table => 'tst_rollback',
          int_table  => 'int_tst_rollback');
      END;
      /
    • Assume that the redefined table performed as expected, and abort the rollback to retain the changes made by online table redefinition and clean up the database objects that enable rollback.
      BEGIN 
        DBMS_REDEFINITION.ABORT_ROLLBACK(
          uname      => 'hr', 
          orig_table => 'tst_rollback',
          int_table  => 'int_tst_rollback');
      END;
      /

  

猜你喜欢

转载自blog.csdn.net/j_ychen/article/details/103280775