千家信息网

Oracle Online Redefinition在线重定义的示例分析

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章将为大家详细讲解有关Oracle Online Redefinition在线重定义的示例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。我们
千家信息网最后更新 2025年12月02日Oracle Online Redefinition在线重定义的示例分析

这篇文章将为大家详细讲解有关Oracle Online Redefinition在线重定义的示例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

我们从一个较复杂的案例出发,讨论复杂变化情况下如何进行Online Redefinition,以及dbms_redefinition包各个关键方法的作用。

一个分区表的重定义动作

我们定义一个数据表T。

SQL> create table t as select object_id, object_name, created from dba_objects;

Table created

SQL> desc t;

Name Type Nullable Default Comments

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

OBJECT_ID NUMBER Y

OBJECT_NAME VARCHAR2(128) Y

CREATED DATE Y

SQL> alter table t add constraint pk_t primary key (object_id);

Table altered

SQL> select count(*) from t;

COUNT(*)

----------

75192

期望的重定义目标有几个:首先使用object_id进行分区、created字段从date类型变为timestamp类型。另外object_name字段改名为object_name_2。中间定义表如下:

(分区,created变类型,object_name字段改名)

SQL> create table t_interim

2 (object_id number,

3 object_name_2 varchar2(128),

4 created timestamp

5 )

6 partition by range(object_id)

7 (

8 partition p1 values less than (10000),

9 partition p2 values less than (50000),

10 partition p3 values less than (maxvalue)

11 )

12 ;

Table created

首先,判断是否可以进行重定义操作。

SQL> set serveroutput on;

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

PL/SQL procedure successfully completed

启动重定义动作。

SQL> exec dbms_redefinition.start_redef_table('SCOTT','T','T_INTERIM',col_mapping => 'object_id object_id, object_name object_name_2, to_timestamp(created) created',options_flag => dbms_redefinition.cons_use_pk);

PL/SQL procedure successfully completed

SQL> set timing on;

注意这个col_mapping映射关系设置,如果存在列名转换,就在这里将列关系映射说明出来。如果需要进行字段类型转换,要书写函数关系将映射计算规则定义出来。

Oracle在线重定义的基础是物化视图技术。此时,我们检查试图user_mviews,可以看到有一个新的物化视图生成,并且存在对应的物化视图日志。

SQL> col query for a20;

SQL> select mview_name, container_name, query, REFRESH_METHOD from user_mviews;

MVIEW_NAME CONTAINER_NAME QUERY REFRESH_METHOD

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

T_INTERIM T_INTERIM select object_id obj FAST

ect_id, object_name

object_name_2, to_ti

mestamp(created) cre

ated from "SCOTT"."T

" "T"

Executed in 0.031 seconds

SQL> select master, log_table from user_mview_logs;

MASTER LOG_TABLE

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

T MLOG$_T

Executed in 0.016 seconds

Start方法创建了一个Fast刷新模式的物化视图对象t_interim。物化视图中最重要的物化视图日志,名称为MLOG$_T。

此时,数据表数据情况如下。

--源数据表和中间数据表已经实现同步

SQL> select count(*) from t;

COUNT(*)

----------

75192

Executed in 0.016 seconds

SQL> select count(*) from t_interim;

COUNT(*)

----------

75192

Executed in 0.031 seconds

--没有DML语句过程,物化视图日志尚空

SQL> select count(*) from mlog$_t;

COUNT(*)

----------

0

Executed in 0.015 seconds

综合上述内容,说明start_redef_table的作用是下面几个方面:

ü 以Interim数据表为名称,创建一个Fast刷新模式的物化视图对象;

ü 从源数据表中将数据加载到Interim中;

ü 创建物化视图日志;

如果在这个过程中,发生DML操作,也就是说在start过程和之后有DML操作,有新数据插入到其中。

SQL> select max(object_id) from t;

MAX(OBJECT_ID)

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

76847

Executed in 0 seconds

SQL> insert into t select object_id+76847, object_name, created from dba_objects;

75199 rows inserted

Executed in 7.297 seconds

SQL> select count(*) from t;

COUNT(*)

----------

150391

Executed in 0.016 seconds

中间表的数据内容保持不变,并且物化视图日志积累了需要刷新的数据条目。

SQL> select count(*) from t_interim;

COUNT(*)

----------

75192

Executed in 0.016 seconds

SQL> select count(*) from mlog$_t;

COUNT(*)

----------

75199

Executed in 0.016 seconds

此时存在数据的不一致和不统一。Oracle推荐要求使用sysnc_interim_table方法将重定义过程中出现的变化数据刷新。

SQL> exec dbms_redefinition.sync_interim_table('SCOTT','T','T_INTERIM');

PL/SQL procedure successfully completed

Executed in 195.937 seconds

刷新7万左右数据,使用了超过三分钟时间。在这个过程中,我们可以看到刷新物化视图过程。

SQL> select * from v$mvrefresh;

SID SERIAL# CURRMVOWNER CURRMVNAME

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

47 13 SCOTT T_INTERIM

刷新开始和结束过程,我们可以看到物化视图刷新过程中的时间变化。

SQL> select name, LAST_REFRESH from user_mview_refresh_times;

NAME LAST_REFRESH

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

T_INTERIM 2013-9-10 9:07:01

SQL> select name, LAST_REFRESH from user_mview_refresh_times;

NAME LAST_REFRESH

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

T_INTERIM 2013-9-10 9:15:28

结束后,我们发现interim表和mlog$_t日志表数据的变化。

SQL> select count(*) from t_interim;

COUNT(*)

----------

150391

Executed in 0.016 seconds

--无变化数据需要刷新了

SQL> select count(*) from mlog$_t;

COUNT(*)

----------

0

Executed in 0.016 seconds

综合上面的实验,我们知道方法sync_interim_table的实质是进行一次物化视图快速刷新。这个方法持续的时间根据不同数据量和物化视图刷新算法来决定,这个过程中,并不会引起很多锁定动作。而且,在在线重定义过程中,这个方法是可以重复执行多次的。

下面,需要将原有数据表中的约束关系刷新到目标结构上。

SQL> set serveroutput on;

SQL> declare

2 error_count number:=0;

3 begin

4 dbms_redefinition.copy_table_dependents(uname => 'SCOTT',orig_table => 'T',int_table => 'T_INTERIM',

5 copy_indexes => dbms_redefinition.cons_orig_params,

6 num_errors => error_count);

7 dbms_output.put_line(to_char(error_count));

8 end;

9 /

0

PL/SQL procedure successfully completed

Finish过程主要完成六个步骤操作:

ü 执行sysnc_interim_table命令,将中间表数据尽可能靠近源数据表;

ü 锁定源数据表T,使之后不能有任何变化发生在这个数据表上;

ü 再次执行sysnc_interim_table命令,这个时候执行的时间不会很长;

ü 将源数据表和Interim数据表表名进行置换;

ü 注销unregistered物化视图,并且删除掉物化视图日志;

ü 释放开在中间表上的锁定;

SQL> exec dbms_redefinition.finish_redef_table('SCOTT','T','T_INTERIM');

PL/SQL procedure successfully completed

Executed in 1.953 seconds

SQL> select count(*) from mlog$_t;

select count(*) from mlog$_t

ORA-00942: 表或视图不存在

检查处理结果。

--按照原定计划,数据表变化成功;

SQL> desc t;

Name Type Nullable Default Comments

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

OBJECT_ID NUMBER Y

OBJECT_NAME_2 VARCHAR2(128) Y

CREATED TIMESTAMP(6) Y

SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);

PL/SQL procedure successfully completed

Executed in 2.719 seconds

分区和主键对象实现成功。

SQL> select partition_name from user_tab_partitions where table_name='T';

PARTITION_NAME

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

P1

P2

P3

Executed in 0.062 seconds

SQL> select constraint_name, constraint_type from user_constraints where table_name='T';

CONSTRAINT_NAME CONSTRAINT_TYPE

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

PK_T P

Executed in 0.062 seconds

我们之前讨论的都是单表情况下的处理,如果是涉及到多表关系,例如外键关系表下的重定义,是怎么处理呢?

关于Oracle Online Redefinition在线重定义的示例分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0