关于分区表的在线重定义

目前项目中有一个问题,存在一个分区表,因为分区规则的问题,使得分区表中的数据分布很不均匀,数据都分区在了默认的maxvalue分区上。现在需要重新划分分区。从常规的角度来看,这中重新分区的问题一般有以下几个步骤。
1.数据备份,采用exp/expdp或者ctas的方式
2.truncate 分区表的数据
3.删除多余的分区,只保留maxvalue的分区
4.使用split partition进行分区
5.使用开始的数据备份,把数据导入。
对于这个问题,如果采用这种方式,势必会需要一定的downtime,如何尽可能保持数据访问的高可用性呢,这个时候可以考虑一下分区表的在线重定义,即重新定义一个分区表,把这两个分区表的ddl进行交换。
我们来简单做一个测试。
创建一个测试表,只含有一个maxvalue分区,然后创建对应的索引。
 CREATE TABLE tab_part_one_par  
   (  
   col1 varchar2(30),  
   col2 DATE  
   )  
   partition BY range(col2)  
   (
   partition tab_part_maxvalue values less than (maxvalue)
   );  
create index inx_part_one_par on   tab_part_one_par(col2) local;
然后尝试插入一些数据。
INSERT INTO tab_part_one_par(col1, col2) SELECT -1, sysdate-365 FROM dual;  
INSERT INTO tab_part_one_par(col1, col2) SELECT 0, sysdate FROM dual;   
INSERT INTO tab_part_one_par(col1, col2) SELECT +1, sysdate+360 FROM dual;  
commit; 
这个时候查看数据的情况。
SQL> SELECT col1,to_char(col2,'yyyy-mm-dd') FROM tab_part_one_par;  
COL1                           TO_CHAR(CO
------------------------------ ----------
-1                             2014-07-15
0                              2015-07-15
1                              2016-07-09
3 rows selected.

接着我们创建另外一个分区表,这个分区表中的分区规则是对的
CREATE TABLE tab_part  
   (  
   col1 varchar2(30),  
   col2 DATE  
   )  
   partition BY range(col2)  
   (  
   partition tab_part_2014 VALUES less than (to_date('2014-08-01','yyyy-mm-dd')),  
   partition tab_part_2015 VALUES less than (to_date('2015-08-01','yyyy-mm-dd')),  
   partition tab_part_2016 VALUES less than (to_date('2016-08-01','yyyy-mm-dd')),
   partition tab_part_maxvalue values less than (maxvalue)
   );  
CREATE INDEX INX_PART ON tab_part(COL2) LOCAL; 
然后我们开始使用在线重定义的方式。
首先验证表是否可以在线重定义
n1@TEST11G>  EXEC dbms_redefinition.can_redef_table('N1','TAB_PART_ONE_PAR',1);  
BEGIN dbms_redefinition.can_redef_table('N1','TAB_PART_ONE_PAR',1); END;
*
ERROR at line 1:
ORA-12089: cannot online redefine table "N1"."TAB_PART_ONE_PAR" with no primary key
ORA-06512: at "SYS.DBMS_REDEFINITION", line 139
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1782
ORA-06512: at line 1
因为分区表中我们定义的是local index,所以创建的唯一性索引不是主键,为了使得这个问题能够顺利处理,我们可以考虑使用rowid
EXEC dbms_redefinition.can_redef_table('N1','TAB_PART_ONE_PAR',dbms_redefinition.cons_use_rowid);  

然后我们调用dbms_redefiniton的三个方法,依次处理。
exec  DBMS_REDEFINITION.CAN_REDEF_TABLE('N1','TAB_PART_ONE_PAR',2);  
exec  DBMS_REDEFINITION.START_REDEF_TABLE('N1','TAB_PART_ONE_PAR','TAB_PART',NULL,2);  
exec  DBMS_REDEFINITION.FINISH_REDEF_TABLE('N1','TAB_PART_ONE_PAR','TAB_PART');  
  

过程很简单,我们来简单验证一下在线重定义的效果。
SELECT * FROM TAB_PART_ONE_PAR partition (TAB_PART_2014); 
COL1                           COL2
------------------------------ ------------------
-1                             15-JUL-14 
SQL> SELECT * FROM TAB_PART_ONE_PAR partition (TAB_PART_2015);  
COL1                           COL2
------------------------------ ------------------
0                              15-JUL-15
SQL> 
SQL> SELECT * FROM TAB_PART_ONE_PAR partition (TAB_PART_2016);  
COL1                           COL2
------------------------------ ------------------
1                              09-JUL-16

可以看到数据已经都同步到三个指定的分区里了。从这个过程来看,效果有点类似exchange partition的效果。但是实现方式还是有很大的不同。
通过这个例子可以看到分区表之间也可以很方便的使用在线重定义来处理,不过需要额外考虑的因素就是权限的分配。

时间: 2024-09-20 19:31:02

关于分区表的在线重定义的相关文章

Oracle 表在线重定义之普通表到分区表

对于一个7*24的在线生产系统来说,修改表定义(DDL)时一件非常痛苦的时,因为如果直接使用 alter语句,将会在表上安放一个排他锁,也就是说在这期间所有的DML和select都无法操作,如果是一 个大表,alter的时间将很长,在这期间应用会受到很大的影响. 幸好,从9i开始,Oracle提供了在线表重定义功能,在修改表定义的同时几乎不影响DML和select语 句,因为排他锁只会在表上出现很短时间.但是在线表重定义需要额外的空间(大致等于原表空间大小 ). 在线表重定义具有如下功能: 修改

【Oracle】利用在线重定义的方式改变普通表为分区表

将普通表改为分区表有如下几种方式: 1 创建一个和原表一样的分区表A_NEW ;    将insert A_NEW SELECT * FROM A;    将表A 命名为A_OLD 将A_NEW 该名为A; 2 利用在先重定义的方式!也是接下来要介绍的方法! 第一种方式需要停止应用对A的写访问;使用在线重定义的方式可以对应用透明! 测试例子如下:1 创建测试表 创建普通表: @bigtab.sql --tom 的大表创建脚本! 创建中间分区PART_TAB,使用PART_TAB来替换bigtab

在线重定义分区表和NOLOGGING APPEND分区表对比

1.模拟大表create table tes_p(it int, ic int, im varchar2(20)); declare     i number(10);begin   for i in 1..1000000  loop  insert into tes_p   values(i,i,'test');  end loop;end;commit;建立主键alter table tes_p add constraint pk_t primary key (it);方法1:在线重定义建立

使用在线重定义重构亿级分区表

在我的印象中,一直以来都会收到一封报警邮件,之前分析过,排查过,最后发现是一个遗留问题,协调开发同学,停业务维护还是有一些难度,最后不了了之了,在今天又突然想起了这件事情,觉得还是需要做点什么. 报警邮件类似下面的形式: ZABBIX-监控系统: ------------------------------------ 报警内容: Disk I/O is overloaded on 10.127.2.134_xx机房_xxxx ----------------------------------

Oracle在线重定义失败后的处理

普通表在线重定义为分区表过程中报错,数值范围超过了分区限制大小,那么想要重新对表进行在线重定义需要经过哪些步骤呢?这个例子记录了处理过程: SALES@ORCL>exec dbms_redefinition.start_redef_table('SALES', 'SALES', 'SALES_P'); BEGIN dbms_redefinition.start_redef_table('SALES', 'SALES', 'SALES_P'); END; * ERROR at line 1: OR

oracle 11g的在线重定义简介

在Oracle9i出现之前,你只能通过MOVE或导出和导入的方式来进行表的重定义,因此表重定义的过程可能相当漫长或者说是一个离线过程,在此期间应用程序对该表的操作将失败.除了这个,如果用exp,我们也不能保证exp的时候该表的数据没有改变(除非单用户),而imp更是一个漫长的过程.为了解决这个问题,Oracle9i在其DBMS_REDEFINITION软件包中引入了在线重定义功能.这个特性对24*7的数据库系统来说非常重要,使用这个技术DBA可以在保持表允许DML语句的情况下修改结构,比如添加列

【Oracle】在线重定义表

Oracle从9i版本开始提供了在线重定义表功能,通过调用DBMS_REDEFINITION包,可以在修改表结构的同时允许DML操作. 在线重定义表具有以下功能: 1 修改表的存储参数 2 可以将表转移到其他表空间 3 增加并行查询选项 4 增加或删除分区 5 重建表以减少碎片 6 将堆表改为索引组织表或相反的操作 7 增加或删除一个列 调用DBMS_REDEFINITION包需要EXECUTE_CATALOG_ROLE角色和以下权限: CREATE ANY TABLE ALTER ANY TA

基于 dbms_redefinition 在线重定义表

      Oracle 支持在线重定义表,也就是说我们可以在修改表结构(DDL)的同时进行相关的DQL.DML操作,使得前端的DML根本感觉不到表结构实际上已经发生了变化,对于用户而言是完全透明的.当然在线重定义期间,前端性能会稍微有所下降.Oracle提供的重定义包dbms_redefinition即是用与完成此操作.其实质是Oracle使用了智能物化视图及物化视图日志的方式.在对象结构重组期间,表现为一个本地对象的复制,重组期间发生的任何变化都会被刷新到最新.   1.在线重定义表的主要功

oracle在线重定义包DBMS_REDIFINITION #

http://blog.itpub.net/post/468/12855 在一个高可用系统中,如果需要改变一个表的定义是一件比较棘手的问题,尤其是对于7×24系统.Oracle提供的基本语法基本可以满足一般性修改,但是对于把普通堆表改为分区表,把索引组织表修改为堆表等操作就无法完成了.而且,对于被大量DML语句访问的表,幸运的是,Oracle从9i版本开始提供了在线重定义表功能,通过调用DBMS_REDEFINITION包,可以在修改表结构的同时允许DML操作. 在线重定义表具有以下功能: 1.