Oracle 12c 新特性 --- Rolling Back Redefinition

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leo__1990/article/details/89919660

1 概念

There is a new ROLLBACK parameter for the FINISH_REDEF_TABLE procedure that tracks DML on a newly redefined table so that changes can be easily synchronized with the original table using the SYNC_INTERIM_TABLE procedure.
在新重新定义的表上跟踪DML的FINISH_REDEF_TABLE过程有一个新的回滚参数,以便可以使用SYNC_INTERIM_TABLE过程轻松地与原始表同步更改。
There is also a new ROLLBACK procedure for the DBMS_REDEFINITION package that initiates the swapping of the redefined table with the original table, therefore effectively rolling back the redefinition changes and returning the table to its original state.
对于DBMS_REDEFINITION包也有一个新的回滚程序,它初始化重新定义的表与原始表的交换,从而有效地回滚重新定义更改,并将表返回到原始状态。
If the results of a redefinition are not acceptable (for example, a performance slow down accessing a newly redefined table), then the redefinition changes can be easily rolled back, therefore saving the DBA time in performing another redefinition to undo the table changes.
如果重新定义的结果是不可接受的(例如,性能减慢访问新定义的表),则重新定义更改可以很容易地回滚,因此可以节省DBA执行另一个重新定义来撤消表更改的时间。

After online table redefinition, you can roll back the table to its definition before online table redefinition while preserving all data manipulation language (DML) changes made to the table.
在在线表重新定义之后,您可以在在线表重新定义之前将表滚回其定义,同时保留对表的所有数据操作语言(DML)更改。

In some cases, you might want to undo an online redefinition of a table. For example, the performance of operations on the table might be worse after the redefinition than it was before the redefinition. In these cases, you can roll back the table to its original definition while preserving all of the DML changes made to the table after it was redefined. Online table redefinition rollback is used mainly when redefinition changes the storage characteristics of the table, and the changes unexpectedly result in degraded performance.
在某些情况下,您可能希望撤消对表的在线重新定义。例如,在重新定义后,表上操作的性能可能比重新定义之前更糟。在这些情况下,您可以将表回滚到它的原始定义,同时保留重新定义后的所有DML更改。在线表重新定义回滚主要用于重定义改变表的存储特性,而更改会导致性能下降。

To enable rollback of online table redefinition, the ENABLE_ROLLBACK parameter must be set to TRUE in the DBMS_REDEFINITION.START_TABLE_REDEF procedure. When this parameter is set to true, Oracle Database maintains the interim table created during redefinition after redefinition is complete. You can run the SYNC_INTERIM_TABLE procedure to synchronize the interim table periodically to apply DML changes made to the redefined table to the interim table. An internal materialized view and materialized view log enables maintenance of the interim table. If you decide to roll back the online table redefinition, then the interim table is synchronized, and Oracle Database switches back to it so that the table has its original definition.
为了启用联机表重新定义的回滚,必须在DBMS_REDEFINITION中设置ENABLE_ROLLBACK参数。START_TABLE_REDEF过程。当这个参数设置为true时,Oracle数据库维护在重新定义完成后在重新定义期间创建的临时表。您可以运行SYNC_INTERIM_TABLE过程,以周期性地同步临时表,将DML更改应用于重新定义的表到临时表。内部物化视图和物化视图日志支持临时表的维护。如果您决定回滚联机表重新定义,那么临时表是同步的,Oracle数据库切换回它,以便表有它的原始定义。

The following restrictions apply to online table redefinition rollback:
以下限制适用于在线表重新定义回滚:

•	When there is no one to one mapping of the original table’s columns to interim table’s columns, there must be no operators or functions in column mappings during redefinition.
•当没有人将原始表的列映射到临时表的列时,在重新定义时,在列映射中必须没有运算符或函数。
There can be operators and functions in column mappings when there is a one to one mapping of the original table’s columns to interim table’s columns.
当将原始表的列映射到临时表的列时,在列映射中可以有运算符和函数。

•	When rollback is enabled for a redefinition, the table cannot be redefined again until the online table redefinition is rolled back or aborted.
•当回滚启用重新定义时,无法重新定义表,直到重新定义在线表重新定义或中止。

2 实验 

这个例子通过改变表的存储特性来说明一个表的在线重新定义。具体来说,这个示例在在线重新定义期间压缩表空间。假设您想在在线重新定义完成后评估表的性能。如果表不像预期的那样执行,那么您希望能够回滚在线重新定义所做的更改。

2.1 创建了原始的表空间和表:
[leowww.cndba.cn ~]$ sqlplus test/test@pdbcndba

SQL*Plus: Release 12.2.0.1.0 Production on Fri Sep 8 00:28:36 2017

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Last Successful login time: Thu Sep 07 2017 23:55:16 +08:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> CREATE TABLESPACE tst_rollback_tbs 
   DATAFILE '/u01/app/oracle/oradata/cndba/pdbcndba/tst_rollback_tbs.dbf' SIZE 10M 
   ONLINE;

Tablespace created.

SQL> CREATE TABLE tst_rollback
    (rllbck_id    NUMBER(6) PRIMARY KEY,
     rllbck_name  VARCHAR2(20)) 
   TABLESPACE tst_rollback_tbs
   STORAGE (INITIAL 2M);

Table created.

SQL> insert into tst_rollback values(1,'www.cndba.cn');

1 row created.

SQL> insert into tst_rollback values(2,'www.cndba.cn');

1 row created.

SQL> commit;

Commit complete.

SQL> select *from tst_rollback;

 RLLBCK_ID RLLBCK_NAME
---------- --------------------
	 1     www.cndba.cn
	 2     www.cndba.cn

SQL> EXEC DBMS_STATS.gather_table_stats(USER, 'TST_ROLLBACK');

PL/SQL procedure successfully completed.

SQL> set long 500
SQL> select dbms_metadata.get_ddl('TABLE','TST_ROLLBACK') from dual;

DBMS_METADATA.GET_DDL('TABLE','TST_ROLLBACK')
--------------------------------------------------------------------------------

  CREATE TABLE "TEST"."TST_ROLLBACK"
   (	"RLLBCK_ID" NUMBER(6,0),
	"RLLBCK_NAME" VARCHAR2(20),
	 PRIMARY KEY ("RLLBCK_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_ROLLBACK_TBS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE

DBMS_METADATA.GET_DDL('TABLE','TST_ROLLBACK')
--------------------------------------------------------------------------------
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS

2.2 为临时表创建一个压缩表空间。
SQL> CREATE TABLESPACE tst_cmp_rollback_tbs 
   DEFAULT ROW STORE COMPRESS ADVANCED
   DATAFILE '/u01/app/oracle/oradata/cndba/pdbcndba/tst_cmp_rollback_tbs.dbf' SIZE 10M 
   ONLINE;

Tablespace created.

2.3 创建一个临时表 int_tst_rollback。
SQL> CREATE TABLE int_tst_rollback
    (rllbck_id    NUMBER(6) PRIMARY KEY,
     rllbck_name  VARCHAR2(20)) 
   TABLESPACE tst_cmp_rollback_tbs
   STORAGE (INITIAL 2M); 

Table created.

2.4 开始重新定义过程。

确保使enable_rollback设置为TRUE,这样在线重新定义所做的更改可以回滚。

SQL> BEGIN
  DBMS_REDEFINITION.START_REDEF_TABLE(
    uname           => 'TEST', 
    orig_table      => 'TST_ROLLBACK',
    int_table       => 'INT_TST_ROLLBACK',
    options_flag    => DBMS_REDEFINITION.CONS_USE_PK,
    enable_rollback => TRUE);
END;
/

PL/SQL procedure successfully completed.
 2.5 复制依赖对象。
SQL> DECLARE
num_errors PLS_INTEGER;
BEGIN
  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(
    uname            => 'TEST', 
    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;
/

PL/SQL procedure successfully completed.

2.6 查询DBA_REDEFINITION_ERRORS视图以检查错误。
您可以忽略与主键和索引相关的错误。
SQL> SET LONG  8000
SQL> SET PAGES 8000
SQL> COLUMN OBJECT_NAME HEADING 'Object Name' FORMAT A20
SQL> COLUMN BASE_TABLE_NAME HEADING 'Base Table Name' FORMAT A10
SQL> COLUMN DDL_TXT HEADING 'DDL That Caused Error' FORMAT A40
SQL> SELECT OBJECT_NAME, BASE_TABLE_NAME, DDL_TXT FROM 
         DBA_REDEFINITION_ERRORS;  2  

Object Name	     Base Table DDL That Caused Error
-------------------- ---------- ----------------------------------------
SYS_C007852	     TST_ROLLBA ALTER TABLE "TEST"."INT_TST_ROLLBACK" AD
		     CK 	D CONSTRAINT "TMP$$_SYS_C0078520" PRIMAR
				Y KEY ("RLLBCK_ID")
				  USING INDEX PCTFREE 10 INITRANS 2 MAXT
				RANS 255
				  STORAGE(INITIAL 65536 NEXT 1048576 MIN
				EXTENTS 1 MAXEXTENTS 2147483645
				  PCTINCREASE 0 FREELISTS 1 FREELIST GRO
				UPS 1
				  BUFFER_POOL DEFAULT FLASH_CACHE DEFAUL
				T CELL_FLASH_CACHE DEFAULT)
				  TABLESPACE "TST_ROLLBACK_TBS"  ENABLE
				NOVALIDATE

2.7 同步临时表int_tst_rollback。
SQL> BEGIN 
  DBMS_REDEFINITION.SYNC_INTERIM_TABLE(
    uname      => 'TEST', 
    orig_table => 'TST_ROLLBACK',
    int_table  => 'INT_TST_ROLLBACK');
END;
/

PL/SQL procedure successfully completed.

2.8 完成重新定义。
SQL> BEGIN
  DBMS_REDEFINITION.FINISH_REDEF_TABLE(
    uname      => 'TEST', 
    orig_table => 'TST_ROLLBACK',
    int_table  => 'INT_TST_ROLLBACK');
END;
/ 

PL/SQL procedure successfully completed.

表tst_rollbck仅在此步骤末尾的一个小窗口中锁定为独占模式。在这之后,表tst_rollback被重新定义,这样它具有int_tst_rollback表的所有属性。在这个示例中,tst_rollbck表的表空间现在被压缩了。

SQL> EXEC DBMS_STATS.gather_table_stats(USER, 'TST_ROLLBACK');

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_STATS.gather_table_stats(USER, 'INT_TST_ROLLBACK');

PL/SQL procedure successfully completed.


SQL> select * from TST_ROLLBACK;

 RLLBCK_ID RLLBCK_NAME
---------- --------------------
	 1 www.cndba.cn
	 2 www.cndba.cn

SQL> select *from INT_TST_ROLLBACK;

 RLLBCK_ID RLLBCK_NAME
---------- --------------------
	 1 www.cndba.cn
	 2 www.cndba.cn


SQL> set long 500
SQL> select dbms_metadata.get_ddl('TABLE','TST_ROLLBACK') from dual;

DBMS_METADATA.GET_DDL('TABLE','TST_ROLLBACK')
--------------------------------------------------------------------------------

  CREATE TABLE "TEST"."TST_ROLLBACK"
   (	"RLLBCK_ID" NUMBER(6,0),
	"RLLBCK_NAME" VARCHAR2(20),
	 PRIMARY KEY ("RLLBCK_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_CMP_ROLLBACK_TBS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTR


SQL> select dbms_metadata.get_ddl('TABLE','INT_TST_ROLLBACK') from dual;

DBMS_METADATA.GET_DDL('TABLE','INT_TST_ROLLBACK')
--------------------------------------------------------------------------------

  CREATE TABLE "TEST"."INT_TST_ROLLBACK"
   (	"RLLBCK_ID" NUMBER(6,0),
	"RLLBCK_NAME" VARCHAR2(20),
	 PRIMARY KEY ("RLLBCK_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_ROLLBACK_TBS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTR

2.8 执行下列操作之一:
2.8.1 假设重新定义的表不像预期的那样执行,并回滚在线重新定义所做的更改。
SQL> BEGIN 
  DBMS_REDEFINITION.ROLLBACK(
    uname      => 'TEST', 
    orig_table => 'TST_ROLLBACK',
    int_table  => 'INT_TST_ROLLBACK');
END;
/

PL/SQL procedure successfully completed.

SQL> select * from INT_TST_ROLLBACK;

 RLLBCK_ID RLLBCK_NAME
---------- --------------------
	 1 www.cndba.cn
	 2 www.cndba.cn

SQL> select *from TST_ROLLBACK;

 RLLBCK_ID RLLBCK_NAME
---------- --------------------
	 1 www.cndba.cn
	 2 www.cndba.cn
--表 TST_ROLLBACK 被回滚到原始状态
SQL> select dbms_metadata.get_ddl('TABLE','TST_ROLLBACK') from dual;

DBMS_METADATA.GET_DDL('TABLE','TST_ROLLBACK')
--------------------------------------------------------------------------------

  CREATE TABLE "TEST"."TST_ROLLBACK"
   (	"RLLBCK_ID" NUMBER(6,0),
	"RLLBCK_NAME" VARCHAR2(20),
	 PRIMARY KEY ("RLLBCK_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_ROLLBACK_TBS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 2097152 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_ROLLBACK_TBS"


SQL> select dbms_metadata.get_ddl('TABLE','INT_TST_ROLLBACK') from dual;

DBMS_METADATA.GET_DDL('TABLE','INT_TST_ROLLBACK')
--------------------------------------------------------------------------------

  CREATE TABLE "TEST"."INT_TST_ROLLBACK"
   (	"RLLBCK_ID" NUMBER(6,0),
	"RLLBCK_NAME" VARCHAR2(20),
	 PRIMARY KEY ("RLLBCK_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_CMP_ROLLBACK_TBS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 ROW STORE COMPRESS ADVANCED LOGGING
  STORAGE(INITIAL 2097152 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_CMP_ROLLBACK_TBS"


2.8.2 假设重新定义的表按照预期执行,并中止回滚,以保留联机表重新定义所做的更改,并清理启用回滚的数据库对象。

SQL> BEGIN 
  DBMS_REDEFINITION.ABORT_ROLLBACK(
    uname      => 'TEST', 
    orig_table => 'TST_ROLLBACK',
    int_table  => 'INT_TST_ROLLBACK');
END;
/

PL/SQL procedure successfully completed.


SQL> select dbms_metadata.get_ddl('TABLE','TST_ROLLBACK') from dual;

DBMS_METADATA.GET_DDL('TABLE','TST_ROLLBACK')
--------------------------------------------------------------------------------

  CREATE TABLE "TEST"."TST_ROLLBACK"
   (	"RLLBCK_ID" NUMBER(6,0),
	"RLLBCK_NAME" VARCHAR2(20),
	 PRIMARY KEY ("RLLBCK_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_CMP_ROLLBACK_TBS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 ROW STORE COMPRESS ADVANCED LOGGING
  STORAGE(INITIAL 2097152 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_CMP_ROLLBACK_TBS"


SQL> select dbms_metadata.get_ddl('TABLE','INT_TST_ROLLBACK') from dual;

DBMS_METADATA.GET_DDL('TABLE','INT_TST_ROLLBACK')
--------------------------------------------------------------------------------

  CREATE TABLE "TEST"."INT_TST_ROLLBACK"
   (	"RLLBCK_ID" NUMBER(6,0),
	"RLLBCK_NAME" VARCHAR2(20),
	 PRIMARY KEY ("RLLBCK_ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_ROLLBACK_TBS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 2097152 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TST_ROLLBACK_TBS"

SQL> select *from TST_ROLLBACK;

 RLLBCK_ID RLLBCK_NAME
---------- --------------------
	 1 www.cndba.cn
	 2 www.cndba.cn
--中止回滚并表INT_TST_ROLLBACK 数据
SQL> select * from INT_TST_ROLLBACK;

no rows selected

3 参考文档

http://docs.oracle.com/database/122/ADMIN/managing-tables.htm#GUID-FDCA40B7-D2EC-4900-98E4-8F1DACEDE0CF

猜你喜欢

转载自blog.csdn.net/leo__1990/article/details/89919660