好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

oracle11g在线重定义(onlineredefinition)介绍

【实验】 对于在线重定义的步骤,这里不再具体说明,我们通过一个实验来演示一下,下面是一个把普通表转换成分区表在线重定义的例子 一、首先创建用户tj,并授予能够完成在线重定义的权限和角色 SQL create user tj identified by tj 2 default tablespace u

【实验】

对于在线重定义的步骤,这里不再具体说明,我们通过一个实验来演示一下,下面是一个把普通表转换成分区表在线重定义的例子

一、首先创建用户tj,并授予能够完成在线重定义的权限和角色

SQL> create user tj identified by tj

2 default tablespace users

3 temporary tablespace temp

4 quota unlimited on users;

User created.

SQL> GRANT CREATE SESSION, CREATE ANY TABLE,ALTER ANY TABLE,

2 DROP ANY TABLE, LOCK ANY TABLE ,SELECT ANY TABLE,

3 CREATE ANY INDEX,CREATE ANY TRIGGER

4 TO TJ;

Grant succeeded.

SQL> GRANT EXECUTE_CATALOG_ROLE TO TJ;

Grant succeeded.

二、使用TJ用户登录,创建表DEMO,作为在线重定义的原始表,在表上添加主键和一个索引

SQL> conn tj/tj

Connected.

SQL> create table demo as select empno,ename,sal,deptno from scott.emp;

Table created.

SQL> select * from demo;

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

14 rows selected.

SQL> alter table demo add constraint demo_pk primary key(empno);

Table altered.

SQL> create index demo_idx on demo(ename);

Index created.

SQL> select object_id,object_name,object_type,status from user_objects;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS

---------- --------------- ------------------- -------

77125 DEMO TABLE VALID

77126 DEMO_PK INDEX VALID

77127 DEMO_IDX INDEX VALID

三、使用CAN_REDEF_TABLE确认表是否可以做在线重定义

SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('TJ', 'DEMO');

PL/SQL procedure successfully completed.

四、创建中间表,当然这是一个空表,使用START_REDEF_TABLE开始在线重定义

SQL> create table demo_tmp

2 partition by range(deptno)

3 (

4 partition p1 values less than (11),

5 partition p2 values less than (21),

6 partition p3 values less than (31)

7 )

8 as

9 select * from demo where 1=2;

Table created.

SQL> select object_id,object_name,object_type,status from user_objects;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS

---------- --------------- ------------------- -------

77129 DEMO_TMP TABLE VALID

77130 DEMO_TMP TABLE PARTITION VALID

77132 DEMO_TMP TABLE PARTITION VALID

77131 DEMO_TMP TABLE PARTITION VALID

77127 DEMO_IDX INDEX VALID

77126 DEMO_PK INDEX VALID

77125 DEMO TABLE VALID

7 rows selected.

SQL> BEGIN

2 DBMS_REDEFINITION.START_REDEF_TABLE('TJ', 'DEMO', 'DEMO_TMP');

3 END;

4 /

PL/SQL procedure successfully completed.

SQL> select object_id,object_name,object_type,status from user_objects;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS

---------- --------------- ------------------- -------

77134 RUPD$_DEMO TABLE VALID

77133 MLOG$_DEMO TABLE VALID

77129 DEMO_TMP TABLE VALID

77130 DEMO_TMP TABLE PARTITION VALID

77132 DEMO_TMP TABLE PARTITION VALID

77131 DEMO_TMP TABLE PARTITION VALID

77127 DEMO_IDX INDEX VALID

77126 DEMO_PK INDEX VALID

77125 DEMO TABLE VALID

9 rows selected.

我们注意到Oracle新建了两张表RUPD$_DEMO和MLOG$_DEMO,其实Oracle在线重定义是通过物化视图的LOG来实现的。做完这一步后,在中间表中也有了相同的数据

SQL> select * from demo;

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

14 rows selected.

SQL> select * from demo_tmp;

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

14 rows selected.

五、使用COPY_TABLE_DEPENDENTS把原始表的权限、约束、索引、物化视图LOG在中间表上创建一份

SQL> set serveroutput on

SQL> var v_err number

SQL> exec DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('TJ', 'DEMO', 'DEMO_TMP', NUM_ERRORS => :V_ERR);

PL/SQL procedure successfully completed.

SQL> print v_err

V_ERR

----------

SQL> select object_id,object_name,object_type,status from user_objects;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS

---------- --------------- ------------------- -------

77137 TMP$$_DEMO_PK0 INDEX VALID

77138 TMP$$_DEMO_IDX0 INDEX VALID

77134 RUPD$_DEMO TABLE VALID

77133 MLOG$_DEMO TABLE VALID

77129 DEMO_TMP TABLE VALID

77130 DEMO_TMP TABLE PARTITION VALID

77132 DEMO_TMP TABLE PARTITION VALID

77131 DEMO_TMP TABLE PARTITION VALID

77127 DEMO_IDX INDEX VALID

77126 DEMO_PK INDEX VALID

77125 DEMO TABLE VALID

11 rows selected.

SQL> select table_name,index_name,status from user_indexes where table_name='DEMO_TMP';

TABLE_NAME INDEX_NAME STATUS

------------------------------ ------------------------------ --------

DEMO_TMP TMP$$_DEMO_IDX0 VALID

DEMO_TMP TMP$$_DEMO_PK0 VALID

这里我们看到,Oracle在中间表DEMO_TMP上又根据原始表DEMO建了两个索引

六、如果在线重定义的时间比较长,而在这个过程中有其他的DML语句操作在原始表上,Oracle通过SYNC_INTERIM_TABLE来做同步

SQL> insert into demo values(1000,'TOMMY',1350,10);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from demo;

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

15 rows selected.

SQL> select * from demo_tmp;

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

14 rows selected.

上面插入一条记录到原始表DEMO中,中间表上是看不到的,这个操作会被记录在MLOG$_DEMO中,需要我们主动同步到DEMO_TMP中

SQL> desc MLOG$_DEMO

Name Null? Type

----------------------------------------------------------------- -------- --------------------------------------------

EMPNO NUMBER(4)

DMLTYPE$$ VARCHAR2(1)

OLD_NEW$$ VARCHAR2(1)

CHANGE_VECTOR$$ RAW(255)

XID$$ NUMBER

SQL> select empno,DMLTYPE$$,OLD_NEW$$ from MLOG$_DEMO;

EMPNO D O

---------- - -

1000 I N

SQL> EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE('TJ', 'DEMO', 'DEMO_TMP');

PL/SQL procedure successfully completed.

SQL> select * from demo;

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

15 rows selected.

SQL> select * from demo_tmp;

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

15 rows selected.

SQL> select empno,DMLTYPE$$,OLD_NEW$$ from MLOG$_DEMO;

no rows selected

严格意义上来说,第六步不是必须的,当做第七步的时候,Oracle会自动同步数据,不过这样会加长表不可用的时间,所以还是建议我们单独做

七、完成在线重定义,在这一步中,要对原始表DEMO以独占的方式锁定。

SQL> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('TJ', 'DEMO', 'DEMO_TMP');

PL/SQL procedure successfully completed.

SQL> select object_id,object_name,object_type,status from user_objects;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS

---------- --------------- ------------------- -------

77129 DEMO TABLE VALID

77130 DEMO TABLE PARTITION VALID

77131 DEMO TABLE PARTITION VALID

77132 DEMO TABLE PARTITION VALID

77125 DEMO_TMP TABLE VALID

77138 DEMO_IDX INDEX VALID

77127 TMP$$_DEMO_IDX0 INDEX VALID

77137 DEMO_PK INDEX VALID

77126 TMP$$_DEMO_PK0 INDEX VALID

9 rows selected.

操作完成后,我们发现RUPD$_DEMO和MLOG$_DEMO被自动删除,另外我们也可以看到重定义的效果了

SQL> SELECT TABLE_NAME, PARTITION_NAME FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'DEMO';

TABLE_NAME PARTITION_NAME

------------------------------ ------------------------------

SQL> select table_name,index_name,status from user_indexes where table_name='DEMO';

TABLE_NAME INDEX_NAME STATUS

------------------------------ ------------------------------ --------

DEMO DEMO_IDX VALID

DEMO DEMO_PK VALID

SQL> select table_name,index_name,status from user_indexes where table_name='DEMO_TMP';

TABLE_NAME INDEX_NAME STATUS

------------------------------ ------------------------------ --------

DEMO_TMP TMP$$_DEMO_IDX0 VALID

DEMO_TMP TMP$$_DEMO_PK0 VALID

SQL> select * from demo partition(p1);

EMPNO ENAME SAL DEPTNO

---------- ---------- ---------- ----------

1000 TOMMY 1350 10

查看更多关于oracle11g在线重定义(onlineredefinition)介绍的详细内容...

  阅读:56次