在线重定义的大致操作流程如下:
(1)创建基础表A,如果存在,就不需要操作。
(2)创建临时的分区表B。
(3)开始重定义,将基表A的数据导入临时分区表B。
(4)结束重定义,此时在DB的Name Directory里,已经将2个表进行了交换。即此时基表A成了分区表,我们创建的临时分区表B 成了普通表。此时我们可以删除我们创建的临时表B。它已经是普通表。
[oracle@hxy ~]$ sqlplus hxy/hxy
SQL*Plus: Release 10.2.0.1.0 - Production on Wed Mar 5 09:45:58 2014
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Error accessing PRODUCT_USER_PROFILE
Warning: Product user profile information not loaded!
You may need to run PUPBLD.SQL as SYSTEM
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
1、创建一个基本表
SQL> create table t( id number(10) primary key,create_date date);
Table created.
2、插入数据
SQL> insert into t select rownum,created from dba_objects;
50361 rows created.
3、创建普通表索引
SQL> create index create_date_ind on t(create_date);
Index created.
SQL> commit;
Commit complete.
4、收集表的统计信息
SQL> exec dbms_stats.gather_table_stats('hxy','t',cascade=>true);
PL/SQL procedure successfully completed.
5、创建一个分区表
SQL> create table t1 (id number primary key, time date) partition by range (time)
2 (partition p1 values less than (to_date('2004-7-1', 'yyyy-mm-dd')),
3 partition p2 values less than (to_date('2005-1-1', 'yyyy-mm-dd')),
4 partition p3 values less than (to_date('2005-7-1', 'yyyy-mm-dd')),
5 partition p4 values less than (maxvalue));
Table created.
6、进行重定义操作
1)检查重定义的合理性
SQL> exec dbms_redefinition.can_redef_table('hxy','t');
PL/SQL procedure successfully completed.
如果分区表和原表列名相同,可以用如下方式进行:
SQL> BEGIN
DBMS_REDEFINITION.start_redef_table(
uname => 'HXY',
orig_table => 't',
int_table => 't1');
END;
/
如果分区表的列名和原表不一致,那么在开始重定义的时候,需要重新指定映射关系
SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE('HXY','t','t1','id id, create_date time', dbms_REDEFINITION.CONS_USE_PK);
PL/SQL procedure successfully completed.
上面标注红色的指定新的映射关系
SQL> select count(*) from t1;数据已经进入了临时表里了
COUNT(*)
----------
50361
2)同步新表数据
SQL> BEGIN
2 dbms_redefinition.sync_interim_table(
3 uname => 'HXY',
4 orig_table => 't',
5 int_table => 't1');
6 END;
7 /
PL/SQL procedure successfully completed.
3)创建临时表的索引,在线重定义只是重定义了数据,索引还需要重新创建
SQL> create index create_date_ind2 on t1(time);
Index created.
4)收集临时表的统计信息
SQL> exec dbms_stats.gather_table_stats('hxy','t1',cascade =>true);
PL/SQL procedure successfully completed.
5)结束在线重定义
SQL> BEGIN
2 dbms_redefinition.finish_redef_table(
3 uname => 'HXY',
4 orig_table => 't',
5 int_table => 't1');
6 END;
7 /
PL/SQL procedure successfully completed.
删除新表
SQL> drop table t1;
Table dropped.
重命名索引
SQL> alter index create_date_ind2 rename to create_date_ind;
Index altered.
核实普通表时否变成分区表了
SQL> select partitioned from user_tables where table_name='t';
PAR
---
YES
SQL> select partition_name from user_tab_partitions where table_name='T';
PARTITION_NAME
------------------------------
P1
P2
P3
P4
SQL> select count(*) from t;
COUNT(*)
----------
50361
SQL> select count(*) from t partition(p3);
COUNT(*)
----------
0
SQL> select count(*) from t partition(p4);
COUNT(*)
----------
50361
SQL>