Oracle Online Redefinition在线重定义(下)

在之前的文章中,我们看到了如何处理单表在线重定义过程。本篇我们来看一下如何进行关联表的重定义过程。

 

4、外键关系表重定义

 

我们先创建出实验数据表。

 

 

SQL> create table t_master as select owner, table_name, tablespace_name, status from dba_tables where 1=0;

Table created

 

SQL> alter table t_master add constraint pk_t_master primary key (owner, table_name);

Table altered

 

Executed in 0.125 seconds

 

SQL> create table t_slave as select owner, table_name, column_name from dba_tab_columns where 1=0;

Table created

 

SQL> alter table T_SLAVE

  2    add constraint pk_t_slave primary key (OWNER, TABLE_NAME, COLUMN_NAME);

Table altered

 

Executed in 0.422 seconds

 

 

T_MASTER和T_SLAVE构成主子表关系,插入数据。

 

 

SQL> insert into t_master select owner, table_name, tablespace_name, status from dba_tables;

2841 rows inserted

 

Executed in 0.157 seconds

 

SQL> commit;

Commit complete

 

Executed in 0 seconds

 

SQL> insert into t_slave select owner, table_name, column_name from dba_tab_cols where (owner, table_name) in (select owner, table_name from dba_tables);

32388 rows inserted

 

Executed in 2.328 seconds

 

SQL> commit;

Commit complete

 

Executed in 0 seconds

 

SQL> alter table T_SLAVE

  2    add constraint fk_t_slave_master foreign key (OWNER, TABLE_NAME)

  3    references t_master (OWNER, TABLE_NAME);

Table altered

 

Executed in 0.266 seconds

 

 

创建interim中间表对象,主要目标是将数据表按照owner进行分区,转化为分区表。

 

 

SQL> create table t_master_interim

  2  (owner varchar2(30),

  3   TABLE_NAME      VARCHAR2(30),

  4   TABLESPACE_NAME VARCHAR2(30),

  5   STATUS          VARCHAR2(8)

  6  )

  7  partition by list(owner)

  8  (

  9     partition p1 values ('SYS'),

 10     partition p2 values (default)

 11  )

 12  ;

 

Table created

 

Executed in 0.156 seconds

 

SQL> create table t_slave_interim

  2  (owner varchar2(30),

  3   table_name varchar2(30),

  4   column_name varchar2(30)

  5  )

  6  partition by list(owner)

  7  (

  8     partition p1 values ('SYS'),

  9     partition p2 values (default)

 10  )

 11  ;

 

Table created

 

Executed in 0.032 seconds

 

 

进入正式的重定义流程。这个过程,如果处于安全和顺序关系看,应该是先子表后主表似乎好一点。笔者选择了先主表后子表的方法。

 

 

--判断是否可以进行在线重定义过程;

SQL> set serveroutput on;

SQL> exec dbms_redefinition.can_redef_table('SCOTT','T_MASTER',options_flag => dbms_redefinition.cons_use_pk);

PL/SQL procedure successfully completed

 

Executed in 0.172 seconds

 

SQL> exec dbms_redefinition.can_redef_table('SCOTT','T_SLAVE',options_flag => dbms_redefinition.cons_use_pk);

PL/SQL procedure successfully completed

 

Executed in 0.015 seconds

 

 

T_MASTER表进行重定义过程。

 

 

SQL> exec dbms_redefinition.start_redef_table('SCOTT','T_MASTER','T_MASTER_INTERIM',col_mapping => 'owner owner, table_name table_name, tablespace_name tablespace_name, status status',options_flag => dbms_redefinition.cons_use_pk);

 

PL/SQL procedure successfully completed

 

Executed in 1.125 seconds

 

SQL> exec dbms_redefinition.sync_interim_table('SCOTT','T_MASTER','T_MASTER_INTERIM');

PL/SQL procedure successfully completed

 

Executed in 0.047 seconds

 

SQL>

SQL> set serveroutput on;

SQL> declare

  2    error_count number:=0;

  3  begin

  4    dbms_redefinition.copy_table_dependents(uname => 'SCOTT',orig_table => 'T_MASTER',

  5                                            int_table => 'T_MASTER_INTERIM',

  6                                            copy_indexes => dbms_redefinition.cons_orig_params,

  7                                            num_errors => error_count);

  8    dbms_output.put_line(to_char(error_count));

  9  end;

 10  /

 

0

 

PL/SQL procedure successfully completed

Executed in 6.766 seconds

 

SQL> exec dbms_redefinition.finish_redef_table('SCOTT','T_MASTER','T_MASTER_INTERIM');

PL/SQL procedure successfully completed

 

Executed in 1.75 seconds

 

 

进行T_SLAVE表重定义过程。

 

 

SQL> exec dbms_redefinition.start_redef_table('SCOTT','T_SLAVE','T_SLAVE_INTERIM',col_mapping => 'owner owner, table_name table_name, column_name column_name',options_flag => dbms_redefinition.cons_use_pk);

PL/SQL procedure successfully completed

Executed in 1.484 seconds

 

SQL> exec dbms_redefinition.sync_interim_table('SCOTT','T_SLAVE','T_SLAVE_INTERIM');

PL/SQL procedure successfully completed

Executed in 0.047 seconds

 

SQL>

SQL> set serveroutput on;

SQL> declare

  2    error_count number:=0;

  3  begin

  4    dbms_redefinition.copy_table_dependents(uname => 'SCOTT',orig_table => 'T_SLAVE',

  5                                            int_table => 'T_SLAVE_INTERIM',

  6                                            copy_indexes => dbms_redefinition.cons_orig_params,

  7                                            num_errors => error_count);

  8    dbms_output.put_line(to_char(error_count));

  9  end;

 10  /

 

0

 

PL/SQL procedure successfully completed

Executed in 6.718 seconds

 

SQL> exec dbms_redefinition.finish_redef_table('SCOTT','T_SLAVE','T_SLAVE_INTERIM');

PL/SQL procedure successfully completed

 

Executed in 1.75 seconds

 

 

最后,我们检查处理结果。

 

 

--分区处理成功;

SQL> select table_name, partition_name from dba_tab_partitions where table_owner='SCOTT' and table_name in ('T_MASTER','T_SLAVE');

 

TABLE_NAME                     PARTITION_NAME

------------------------------ ------------------------------

T_MASTER                       P1

T_MASTER                       P2

T_SLAVE                        P1

T_SLAVE                        P2

 

Executed in 0.031 seconds

 

 

约束中存在一些需要额外处理的地方。

 

 

SQL> select constraint_name, constraint_type, R_CONSTRAINT_NAME from dba_constraints where wner='SCOTT' and table_name in ('T_MASTER','T_SLAVE');

 

CONSTRAINT_NAME                CONSTRAINT_TYPE R_CONSTRAINT_NAME

------------------------------ --------------- ------------------------------

TMP$$_FK_T_SLAVE_MASTER0       R               TMP$$_PK_T_MASTER0

SYS_C0011276                   C              

SYS_C0011275                   C              

SYS_C0011274                   C              

PK_T_SLAVE                     P              

FK_T_SLAVE_MASTER              R               PK_T_MASTER

SYS_C0011272                   C              

SYS_C0011271                   C              

PK_T_MASTER                    P              

 

9 rows selected

 

Executed in 0.141 seconds

 

 

由于是分别进行的重定义动作,中间可能有关联裹挟的情况,所以需要额外进行一些处理。主要目标是将Interim数据表删除掉。

 

SQL> drop table t_slave_interim;

Table dropped

 

Executed in 0.438 seconds

 

SQL> alter table t_slave drop constraint "TMP$$_FK_T_SLAVE_MASTER0";

Table altered

 

Executed in 0.031 seconds

 

SQL> drop table t_master_interim purge;

Table dropped

 

Executed in 0.094 seconds

 

 

检查约束情况。

 

 

SQL> select constraint_name, constraint_type, R_CONSTRAINT_NAME from dba_constraints where wner='SCOTT' and table_name in ('T_MASTER','T_SLAVE');

 

CONSTRAINT_NAME                CONSTRAINT_TYPE R_CONSTRAINT_NAME

------------------------------ --------------- ------------------------------

PK_T_MASTER                    P              

PK_T_SLAVE                     P              

FK_T_SLAVE_MASTER              R               PK_T_MASTER

SYS_C0011271                   C              

SYS_C0011272                   C              

SYS_C0011274                   C              

SYS_C0011275                   C              

SYS_C0011276                   C              

 

8 rows selected

 

Executed in 0.125 seconds

 

 

重定义成功。

 

5、结论和讨论

 

Oracle在线重定义是一种非常强大的定义工具。这个系列只是介绍了该特性中最常用的一些流程和方法。其他一些诸如register对象和重命名的方法,在一些特定场合下有比较好的使用空间。

 

应该说,Oracle在线重定义是一种平滑性能、减少锁定、提高系统整体可用性的解决方案。从操作时间和空间消耗上,在线重定义并不具有很高的优势。对于7*24小时的系统,该特性是一种不错的选择。

 

时间: 2024-10-23 14:18:27

Oracle Online Redefinition在线重定义(下)的相关文章

Oracle Online Redefinition在线重定义(中)

上篇中,我们简单地介绍了如何使用Oracle在线重定义特性进行数据表Online的结构变动操作.本篇我们从一个较复杂的案例出发,讨论复杂变化情况下如何进行Online Redefinition,以及dbms_redefinition包各个关键方法的作用.   3.一个分区表的重定义动作   我们定义一个数据表T.     SQL> create table t as select object_id, object_name, created from dba_objects; Table cr

Oracle Online Redefinition在线重定义(上)

面对越来越多的7*24系统,运维人员进行工作可用的时间窗口变的越来越小.就在有限的时间窗口中,硬件检修.网络改造配置占据了很多时间.对数据库对象进行日常维护,越来越成为我们需要关注的问题.   进行数据重排.表分区.字段类型修改.字段增改这样的操作,在开发和测试环境上是比较容易进行的.即使数据表很大,操作耗时可能会很高,我们也能够通过一些非技术的手段赢取操作时间窗.但是对于投产系统而言,操作过程中的长时间锁定可能是业务不能接受的.这个时候,就可以考虑Oracle的一些Online操作技术.  

oracle 11g的在线重定义简介

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

【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

Oracle表的在线重定义(一)

好处: When a table is redefined online, it is accessible to both queries and DML during much of the redefinition process.  内部机制: Typically, the table is locked in the exclusive mode only during a very small window that is independent of the size of the

oracle 10g在线重定义新特性:关联对象自动重命名(一)

10g的在线重定义解决这个问题.如果对象是利用COPY_TABLE_DEPENDENTS创建的,那么这些关联的对象在重定义操作完成后,自动改为原始的名称.如果是手工创建的关联对象,则可以利用REGISTER_DEPENDENT_OBJECT过程,所有执行了REGISTER_DEPENDENT_OBJECT过程的关联对象,都会在重定义操作完成后自动重命名. 这篇文章来看COPY_TABLE_DEPENDENTS的例子. 首先看看9i下的例子: SQL> SELECT * FROM V$VERSIO

oracle在线重定义包DBMS_REDIFINITION #

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

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 10g在线重定义新特性:关联对象自动重命名(二)

9i的在线重定义存在一个问题,执行完在线重定义后,表的名称虽然保持不变,但是索引.约束.触发器等关联对象的名称会发生变化,有时候这会带来一定的问题,而要在事后手工修改,会比较麻烦. 10g的在线重定义解决这个问题.如果对象是利用COPY_TABLE_DEPENDENTS创建的,那么这些关联的对象在重定义操作完成后,自动改为原始的名称.如果是手工创建的关联对象,则可以利用REGISTER_DEPENDENT_OBJECT过程,所有执行了REGISTER_DEPENDENT_OBJECT过程的关联对