今天查了下v$session_longops,发现有一条命令执行了好久,只是简简单单的
select count(1) from trans_tmp;
随手就查了下表大小
SQL> set linesize 9999
SQL> col owner format a10
SQL> col segment_name format a20
SQL> /
OWNER SEGMENT_NAME BYTES/1024/1024
---------- -------------------- ---------------
ORICLIENT TRANS_TMP 7391
罪过!罪过!竟然一直没管过这张表,看来是上次做表分区漏掉了,那么这次就补上吧,因为正常的建立表分区再rename会影响到应用,所以采用在线重定义的方式来做
1.首先使用 DBMS_REDEFINITION.CAN_REDEF_TABLE来查询表是否可以使用重定义exec DBMS_REDEFINITION.CAN_REDEF_TABLE(用户名,表名)
SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('ORI','TRANS_TMP');
BEGIN DBMS_REDEFINITION.CAN_REDEF_TABLE('ORI','TRANS_TMP'); END;
*
第 1 行出现错误:
ORA-12089: 不能联机重新定义无主键的表 "ORI"."TRANS_TMP"
ORA-06512: 在 "SYS.DBMS_REDEFINITION", line 137
ORA-06512: 在 "SYS.DBMS_REDEFINITION", line 1478
ORA-06512: 在 line 1
出错,提示没有主键,所以先建立主键
alter table ori.trans_tmp add constraint pk_trans_tmp primary key(id);
成功后再次执行
SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('ORICLIENT','TRANS_PG_MID_TMP');
PL/SQL 过程已成功完成。
2.需要创建分区表,表结构要和原表一样,这是肯定的,我只是要把原来的大表拆成分区表,这里使用时间来做range分区
CREATE TABLE trans_t_new PARTITION BY RANGE (curdatetime)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2010-1-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('2011-1-1', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('2012-1-1', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE))
as select * from ori.trans_tmp where 1=0;
这里的maxvalue会存所有不在其他range里的数据,这以后还得手动增加吧,不然p4分区会非常大的。
3.开始执行重定义
EXEC DBMS_REDEFINITION.START_REDEF_TABLE(‘ORI', 'TRANS_TMP', 'TRANS_T_NEW');
4.结束重定义,会把在执行重定义的时候原表后增加的数据补进去
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(‘ORI', 'TRANS_TMP', 'TRANS_T_NEW');
这样就ok了,trans_tmp已经是分区表了
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/25680865/viewspace-714165/
,如需转载,请注明出处,否则将追究法律责任。