dbms_redefinition在线重定义表

oracle 9i提供了dbms_redefinition包来实现数据库的表的在线重定义功能。在实际的应用上,我们可以利用这个包来进行:(1)堆表与分区之间进行转换。(2)重建表以减少HWM。10g能shrink,9i如果用move tablespace and rebuild index在move的时候会锁表,如果想实现在线降低HWM,估计只能用这个了。(3)在线更改表结构,如更改列的前后顺序,将column_a,column_b改成column_b,column_a。

下面就来看看这个包的内容:

需要说明的是,如果采用主键作为在线重定义的关联,options_flag 为1,此为默认值,如果表中没有主键,可以用rowid作为在线重定义的关联,但是options_flag 要为2;col_mapping为需要对应的字段,如需要将原表(orig_table )的id字段和中间临时表(int_table)的col_id 字段对于,则需要col_mapping=>’ID COL_ID’,如果完全对应,col_mapping为null,此为默认值。

下面来看看这个包使用的例子(用PK来同步):

好,我们现在已经构造了一个xxx表,且由于经常insert和delete,这个表的HWM比较高,其中浪费的block已经比较多。

我们看到这个表的HWM有30652个block,而平均使用的block只有437个block,98%是浪费的。

下面进行这个表的在线重定义,首先建立中间临时表YYY:

由于我们采用的是PK做关联,因此不必使用options_flag=>2。

让我们来对xxx表经常在线的操作,如update,insert等等的操作:

在这里,我们看到,当dbms_redefinition.START_REDEF_TABLE开始时候,xxx表和yyy表的记录数是一样的,但是当xxx表进行更新的时,yyy表还保持着在start时候的状态。(我们可以用dbms_redefinition.SYNC_INTERIM_TABLE进行同步,待会会介绍)

我们来看一下此时的xxx表和yyy表的HWM情况:

我们看到xxx表达还是有98%左右的浪费,而yyy只有8%左右的浪费。

进行一次数据同步(其实是一次物化视图的刷新,后面会介绍):

完成同步后,xxx和yyy保持一致,但是由于是在线系统,xxx表仍然会有变化,我们在这边做同步的目的是为了在做finish_redef_table能同步较少的数据。

最后,我们结束同步,其内部操作是是将xxx表和yyy表的名称互换,我们看看结束同步后HWM的变化:

在这里,我们看到xxx表和yyy的HWM的使用率完全倒过来了,也就是说,将xxx表和yyy表的名字进行了互换。(但是表中的原来的PK还跟着原来的表)。
这样,我们就在线的完成了降低HWM。

同样的,我们也可以用rowid来进行表的在线重定义(不适合IOT表),操作步骤在这边就不一步一步解释了,基本就PK的一样,见下面的实验:

不过需要注意的时候,用rowid在线重定义,重定义之后的表会生成一个隐藏的M_ROW$$列,我们可以unused后,drop它:

如果深入一点,观察一下这个包的操作过程,通过trace这个包的执行过,我们在start的时候,发现有以下的操作:

我们发现oracle是通过一个prebuilt 物化视图来实现重定义的,因此,使用物化视图的一些限制在这里同样适用。

其他注意点:(1)索引名称改变。(2)如果数据量比较大,需要较多的undo。(3)如果遇到意外,需要abort_redef_table 将物化视图取消掉。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据