将普通表改为分区表有如下几种方式:
1 创建一个和原表一样的分区表A_DBMS
iis7站长之家 ;
将insert A_NEW SELECT * FROM A;
将表A 命名为A_OLD 将A_NEW 该名为A;
2 利用在先重定义的方式!也是接下来要介绍的方法!
第一种方式需要停止应用对A的写访问;使用在线重定义的方式可以对应用透明!
测试例子如下:
1 创建测试表
创建普通表:
@bigtab.sql --tom 的大表创建脚本!
创建中间分区PART_TAB,使用PART_TAB来替换bigtab
www.linuxidc.com@linuxidc> CREATE TABLE PART_TAB
2 ( ID NUMBER,
3 OWNER VARCHAR2(30) NOT NULL ENABLE,
4 OBJECT_NAME VARCHAR2(30) NOT NULL ENABLE,
5 SUBOBJECT_NAME VARCHAR2(30),
6 OBJECT_ID NUMBER NOT NULL ENABLE,
7 DATA_OBJECT_ID NUMBER,
8 OBJECT_TYPE VARCHAR2(19),
9 CREATED DATE NOT NULL ENABLE,
10 LAST_DDL_TIME DATE NOT NULL ENABLE,
11 TIMESTAMP VARCHAR2(19),
12 STATUS VARCHAR2(7),
13 TEMPORARY VARCHAR2(1),
14 GENERATED VARCHAR2(1),
15 SECONDARY VARCHAR2(1),
16 NAMESPACE NUMBER NOT NULL ENABLE,
17 EDITION_NAME VARCHAR2(30)
18 ) PARTITION BY RANGE (id)
19 (PARTITION P1 VALUES LESS THAN (100000),
20 PARTITION P2 VALUES LESS THAN (200000),
21 PARTITION P3 VALUES LESS THAN (300000),
22 PARTITION P4 VALUES LESS THAN (400000),
23 PARTITION P5 VALUES LESS THAN (MAXVALUE)
24 );
Table created.
2 验证是否可以进行在线重定义:
www.linuxidc.com@linuxidc> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(user, 'BIGTAB', DBMS_REDEFINITION.CONS_USE_PK);
PL/SQL procedure successfully completed.
3 执行表的在线重定义:
www.linuxidc.com@linuxidc> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'BIGTAB', 'PART_TAB');
PL/SQL procedure successfully completed.
第一步完成的时候 可以在session 2中查看:
www.linuxidc.com@linuxidc> SELECT COUNT(*) FROM BIGTAB;
COUNT(*)
----------
500000
www.linuxidc.com@linuxidc> SELECT COUNT(*) FROM PART_TAB PARTITION (P2);
COUNT(*)
----------
100000
www.linuxidc.com@linuxidc> SELECT COUNT(*) FROM PART_TAB PARTITION (P3);
COUNT(*)
----------
100000
www.linuxidc.com@linuxidc>
4 执行把中间表的内容和数据源表进行同步。
在session 2 中对原表进行dml 操作并提交:
www.linuxidc.com@linuxidc>update bigtab set id=id-1 where rownum <10000;
9999 rows updated.
www.linuxidc.com@linuxidc> commit;
Commit complete.
在session 1 对表进行同步变化的数据!根据数据量的大小要等待相应的时间!
www.linuxidc.com@linuxidc>execute dbms_redefinition.sync_interim_table(user,'BIGTAB','PART_TAB');
PL/SQL procedure successfully completed.
同步完成之后再次在session 中查询中间表并没有和原表一样:
www.linuxidc.com@linuxidc> SELECT ID FROM BIGTAB WHERE ROWNUM < 10;
ID
----------
1
2
3
4
5
6
7
8
9
9 rows selected.
www.linuxidc.com@linuxidc>
www.linuxidc.com@linuxidc> SELECT ID FROM PART_TAB WHERE ROWNUM < 10;
ID
----------
1
2
3
4
5
6
7
8
9
9 rows selected.
等到结束之后才可以再次查看的时候 两边一致!
5 执行结束在线定义过程
www.linuxidc.com@linuxidc> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(user, 'BIGTAB', 'PART_TAB');
PL/SQL procedure successfully completed.
6 查看数据字典,可以看到改表已经成为了分区表。
www.linuxidc.com@linuxidc> select table_name,partition_name,high_value from user_tab_partitions;
TABLE_NAME PARTITION_NAME HIGH_VALUE
--------------- --------------- ---------------
BIGTAB P1 100000
BIGTAB P2 200000
BIGTAB P3 300000
BIGTAB P4 400000
BIGTAB P5 MAXVALUE
www.linuxidc.com@linuxidc> SELECT COUNT(*) FROM BIGTAB;
COUNT(*)
----------
6264
www.linuxidc.com@linuxidc> SELECT COUNT(*) FROM PART_TAB PARTITION (P2);
COUNT(*)
----------
6246
至此普通表转为分区操作完成
如果执行在线重定义的过程中出错,可以在执行dbms_redefinition.start_redef_table之后到执行dbms_redefinition.finish_redef_table之前的时间里执行:dbms_redefinition.abort_redef_table(user, 't', 'part_tab')以放弃执行在线重定义。