ORACLE Table online convert into Partition table

在线重定义的大致操作流程如下: 
1.创建基础表A,如果存在,就不需要操作。 
2.创建临时的分区表B。 
3.开始重定义,将基表A的数据导入临时分区表B。 
4.结束重定义,此时在DB的 Name Directory里,已经将2个表进行了交换。即此时基表A成了分区表,我们创建的临时分区表B 成了普通表。 此时我们可以删除我们创建的临时表B。它已经是普通表。 
 
如果过程中原表还会变化,考虑用物化视图日志记录并应用在目标表

示例: 
1. 创建基本表和索引 
sql> sqlplus / as sysdba;
 
sql> grant select on dba_objects to hr;
 
sql> conn hr/hr; 
 
sql> create table unpar_table ( id number(10) primary key, create_date date ); 
 
sql> insert into unpar_table select rownum, created from dba_objects; 
 
sql> create index create_date_ind on unpar_table(create_date); 
 
sql> commit; 
 
2. 收集表的统计信息 
sql> exec dbms_stats.gather_table_stats('hr', 'unpar_table', cascade => true); 
 
pl/sql 过程已成功完成。 
 
3. 创建临时分区表 
sql> create table par_table (id number primary key, time date) partition by range (time) 
 
    (partition p1 values less than (to_date('2005-1-1', 'yyyy-mm-dd')), 
 
    partition p2 values less than (to_date('2010-1-1', 'yyyy-mm-dd')), 
 
    partition p3 values less than (to_date('2011-1-1', 'yyyy-mm-dd')), 
 
    partition p4 values less than (maxvalue)); 
 
4. 进行重定义操作 
4.1 检查重定义的合理性 
 
sql> conn system/password
 
sql> exec dbms_redefinition.can_redef_table('hr', 'unpar_table'); 
 
4.2 如果4.1 没有问题,开始重定义,这个过程可能要等一会。 
 
这里要注意:如果分区表和原表列名相同,可以用如下方式进行: 
 
SQL> BEGIN 
 
DBMS_REDEFINITION.start_redef_table( 
 
uname => 'hr', 
 
orig_table => 'unpar_table', 
 
int_table => 'par_table'
 
col_mapping => 'ID ID, create_date TIME'); 
 
END; 
 
 
这一步操作结束后,数据就已经同步到这个临时的分区表里来了。 
 
4.3 同步新表(这是可选的操作) 
 
SQL> BEGIN 
 
    dbms_redefinition.sync_interim_table( 
 
    uname => 'hr', 
 
    orig_table => 'unpar_table', 
 
    int_table => 'par_table'); 
 
    END; 
 
    / 
 
PL/SQL 过程已成功完成。 
 
4.4 创建索引,在线重定义只重定义数据,索引还需要单独建立。 
 
sql> create index create_date_ind2 on par_table(time); 
 
索引已创建。 
 
4.5 收集新表的统计信息 
 
sql> exec dbms_stats.gather_table_stats('hr', 'par_table', cascade => true); 
 
pl/sql 过程已成功完成。 
 
4.6 结束重定义 
 
SQL> BEGIN 
 
  2 dbms_redefinition.finish_redef_table( 
 
  3 uname => 'hr', 
 
  4 orig_table => 'unpar_table', 
 
  5 int_table => 'par_table'); 
 
  6 END; 
 
  7 / 
 
PL/SQL 过程已成功完成。 
 
结束重定义的意义:基表unpar_table 和临时分区表par_table 进行了交换。 此时临时分区表par_table成了普通表,我们的基表unpar_table成了分区表。 
 
我们在重定义的时候,基表unpar_table是可以进行DML操作的。 只有在2个表进行切换的时候会有短暂的锁表。 
 
5. 删除临时表 
 
SQL> DROP TABLE par_table; 
 
6. 索引重命名 
 
SQL> ALTER INDEX create_date_ind2 RENAME TO create_date_ind; 
 
7. 验证 
 
sql> select partitioned from user_tables where table_name = 'UNPAR_TABLE'; 
 
par 
 
--- 
 
yes 
 
sql> select partition_name from user_tab_partitions where table_name = 'UNPAR_TABLE'; 
 
partition_name 
 
------------------------------ 
 
p1 
 
p2 
 
p3 
 
p4 
 
sql> select count(*) from unpar_table; 
 
  count(*) 
 
---------- 
 
     72288 
 
sql> select count(*) from unpar_table partition (p4); 
 
  count(*) 
 
---------- 
 
     72288 
 
sql> 

Comments

Popular posts from this blog

Nginx Proxy & Load Balance & LNMP

Snort+barnyard2+Snorby CentOS 6.5_64 Installation

ORACLE Error