iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Online Redefinition在线重定义(二)--单表复杂案例
  • 224
分享到

Online Redefinition在线重定义(二)--单表复杂案例

2024-04-02 19:04:59 224人浏览 独家记忆
摘要

在上一篇博文(Online Redefinition在线重定义(一))中,简单地介绍了oracle在线重定义特性进行数据表在线结构变动操作。本篇博文将演示一个较复杂的案例,在案例的复杂变化中进行在线

在上一篇博文(Online Redefinition在线重定义(一))中,简单地介绍了oracle在线重定义特性进行数据表在线结构变动操作。本篇博文将演示一个较复杂的案例,在案例的复杂变化中进行在线重定义及dbms_redefinition包各个关键方法的作用。

 

普通表改造分区表

 

--创建一张普通表t_wjq1

SEIANG@seiang11g>create table t_wjq1 as select object_id,object_name,created from dba_objects;

Table created.

 

SEIANG@seiang11g>desc t_wjq1

 Name                                                                                                              Null?    Type

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

 OBJECT_ID                                                                                                                NUMBER

 OBJECT_NAME                                                                                                              VARCHAR2(128)

 CREATED                                                                                                                  DATE

 

SEIANG@seiang11g>select count(*) from t_wjq1;

 

  COUNT(*)

----------

     86997

 

 

--在表t_wjq1的object_id列上创建主键

SEIANG@seiang11g>alter table t_wjq1 add constraint pk_t_wjq1_id primary key(object_id);

Table altered.

 

SEIANG@seiang11g>

SEIANG@seiang11g>select index_name,index_type,table_owner,table_name from user_indexes;

 

INDEX_NAME                     INDEX_TYPE                  TABLE_OWNER                    TABLE_NAME

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

PK_T_WJQ1_ID                   NORMAL                      SEIANG                         T_WJQ1

 

 

需求:重定义的内容有以下几个:
(1)使用object_id进行分区
(2)created字段从date类型变为timestamp类型
(3)object_name字段改名为object_name_2。


--创建一张中间表t_wjq1_interim

SEIANG@seiang11g>create table t_wjq1_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 (5000),

  9     partition p2 values less than (10000),

 10     partition p3 values less than (50000),

 11     partition p4 values less than (maxvalue)

 12  );

 

Table created.

 

 

--查看中间表的分区情况

SEIANG@seiang11g>select table_name,partition_name from user_tab_partitions;

 

TABLE_NAME                     PARTITION_NAME

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

T_WJQ1_INTERIM                 P4

T_WJQ1_INTERIM                 P3

T_WJQ1_INTERIM                 P2

T_WJQ1_INTERIM                 P1

 

 

--首先,查看t_wjq1表是否支持重定义操作

SEIANG@seiang11g>exec dbms_redefinition.can_redef_table('SEIANG','T_WJQ1',options_flag=>dbms_redefinition.cons_use_pk);

 

PL/sql procedure successfully completed.

 

Elapsed: 00:00:00.02

 

 

--开始重定义操作

SEIANG@seiang11g>exec dbms_redefinition.start_redef_table('SEIANG','T_WJQ1','T_WJQ1_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.

Elapsed: 00:00:01.42

 

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

 

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


SEIANG@seiang11g>select mview_name, container_name, query, REFRESH_METHOD from user_mviews;

 

MVIEW_NAME                     CONTAINER_NAME                 QUERY                                                          REFRESH_

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

T_WJQ1_INTERIM                 T_WJQ1_INTERIM                 select object_id object_id, object_name object_name_2, to_timestamp(created) cre FAST

 

Elapsed: 00:00:00.02

SEIANG@seiang11g>

SEIANG@seiang11g> select master,log_table from user_mview_logs;

 

MASTER                         LOG_TABLE

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

T_WJQ1                         MLOG$_T_WJQ1

 

Elapsed: 00:00:00.00

 

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

 

--查看原始表和中间表的数据量

SEIANG@seiang11g>select count(*) from t_wjq1;

 

  COUNT(*)

----------

     86997

 

Elapsed: 00:00:00.01

SEIANG@seiang11g>

SEIANG@seiang11g>select count(*) from t_wjq1_interim;

 

  COUNT(*)

----------

     86997

 

Elapsed: 00:00:00.01

 

--没有DML操作,所以物化视图日志尚空

SEIANG@seiang11g>select * from mlog$_t_wjq1;

 

no rows selected

 

Elapsed: 00:00:00.00

 

SEIANG@seiang11g>select count(*) from mlog$_t_wjq1;

 

  COUNT(*)

----------

         0

 

Elapsed: 00:00:00.00

 

 

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

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

(2)从源数据表中将数据加载到Interim中;

(3)创建物化视图日志;

 

 

如果在这个过程中,发生了DML操作,也就是说在start过程或者之后有DML操作,有新数据插入或修改,如下操作所示:

 

--查看t_wjq1表的数据量和最大的object_id值

SEIANG@seiang11g>select count(*) from t_wjq1;

 

  COUNT(*)

----------

     86997

 

Elapsed: 00:00:00.00

 

SEIANG@seiang11g>select max(object_id) from t_wjq1;

 

MAX(OBJECT_ID)

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

         89700

 

Elapsed: 00:00:00.01

 

 

--模拟DML操作:在表t_wjq1中插入数据库

SEIANG@seiang11g>insert into t_wjq1 select object_id+90000,object_name,created from dba_objects;

 

87006 rows created.

 

Elapsed: 00:00:05.13

 

 

--再次查看原始表t_wjq1、中间表t_wjq1_interim以及物化视图日志试图的变化

SEIANG@seiang11g>select count(*) from t_wjq1;

 

  COUNT(*)

----------

    174003

 

Elapsed: 00:00:00.01

SEIANG@seiang11g>

SEIANG@seiang11g>select count(*) from t_wjq1_interim;

 

  COUNT(*)

----------

     86997

 

Elapsed: 00:00:00.00

 

SEIANG@seiang11g>select count(*) from mlog$_t_wjq1;

 

  COUNT(*)

----------

     87006

 

Elapsed: 00:00:00.01

 

发现:中间表的数据内容保持不变,并且物化视图日志积累了需要刷新的数据条目。此时存在数据的不一致和不统一。Oracle推荐要求使用sysnc_interim_table方法将重定义过程中出现的变化数据刷新。

 

 

--刷新8万多条数据,使用了超过四分钟时间。在这个过程中,我们可以看到刷新物化视图过程。

SEIANG@seiang11g>exec dbms_redefinition.sync_interim_table('SEIANG','T_WJQ1','T_WJQ1_INTERIM');

 

PL/SQL procedure successfully completed.

 

Elapsed: 00:04:18.33

 

SEIANG@seiang11g>select * from v$mvrefresh;

 

       SID    SERIAL# CURRMVOWNER                     CURRMVNAME

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

        41      14059 SEIANG                          T_WJQ1_INTERIM

 

 

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

SEIANG@seiang11g>alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';

 

Session altered.

 

SEIANG@seiang11g>

SEIANG@seiang11g>select name, LAST_REFRESH from user_mview_refresh_times;

 

NAME                           LAST_REFRESH

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

T_WJQ1_INTERIM                 2017-09-06 13:59:57

 

SEIANG@seiang11g>select name, LAST_REFRESH from user_mview_refresh_times;

 

NAME                           LAST_REFRESH

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

T_WJQ1_INTERIM                 2017-09-06 14:22:20

 

 

--刷新结束后,发现t_wjq1_interim表和mlog$_t_wjq1日志表数据的变化

SEIANG@seiang11g>select count(*) from t_wjq1_interim;

 

  COUNT(*)

----------

    174003

 

SEIANG@seiang11g>

SEIANG@seiang11g>select count(*) from t_wjq1;

 

  COUNT(*)

----------

    174003

 

SEIANG@seiang11g>

SEIANG@seiang11g>select count(*) from mlog$_t_wjq1;

 

  COUNT(*)

----------

         0

说明无变化数据需要刷新了

 

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

 

 

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

SEIANG@seiang11g>declare

  2     error_count number:=0;

  3  begin

  4     dbms_redefinition.copy_table_dependents(uname => 'SEIANG',orig_table => 'T_WJQ1',int_table => 'T_WJQ1_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  /

 

PL/SQL procedure successfully completed.

 

Elapsed: 00:00:05.29

 

SEIANG@seiang11g>select index_name,index_type,table_owner,table_name from user_indexes;

 

INDEX_NAME                     INDEX_TYPE                  TABLE_OWNER                    TABLE_NAME

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

TMP$$_PK_T_WJQ1_ID0            NORMAL                      SEIANG                         T_WJQ1_INTERIM

PK_T_WJQ1_ID                   NORMAL                      SEIANG                         T_WJQ1

I_MLOG$_T_WJQ1                 NORMAL                      SEIANG                         MLOG$_T_WJQ1

 

Elapsed: 00:00:00.04

 

 

SEIANG@seiang11g>select master,log_table from user_mview_logs;

 

MASTER                         LOG_TABLE

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

T_WJQ1                         MLOG$_T_WJQ1

 

 

 

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

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

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

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

(4)将源数据表和Interim数据表表名进行置换;

(5)注销unreGIStered物化视图,并且删除掉物化视图日志;

(6)释放开在中间表上的锁定;

 

 

SEIANG@seiang11g> exec dbms_redefinition.finish_redef_table('SEIANG','T_WJQ1','T_WJQ1_INTERIM');

 

PL/SQL procedure successfully completed.

 

Elapsed: 00:00:02.11

SEIANG@seiang11g>select master,log_table from user_mview_logs;

 

no rows selected

 

Elapsed: 00:00:00.02

SEIANG@seiang11g>

SEIANG@seiang11g>select * from mlog$_t_wjq1;

select * from mlog$_t_wjq1

              *

ERROR at line 1:

ORA-00942: table or view does not exist

 

 

SEIANG@seiang11g>select index_name,index_type,table_owner,table_name from user_indexes;

 

INDEX_NAME                     INDEX_TYPE                  TABLE_OWNER                    TABLE_NAME

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

TMP$$_PK_T_WJQ1_ID0            NORMAL                      SEIANG                         T_WJQ1_INTERIM

PK_T_WJQ1_ID                   NORMAL                      SEIANG                         T_WJQ1

 

 

--检查重定义的结果

SEIANG@seiang11g>desc t_wjq1

 Name                                                                                                              Null?    Type

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

 OBJECT_ID                                                                                                                NUMBER

 OBJECT_NAME_2                                                                                                            VARCHAR2(128)

 CREATED                                                                                                                  TIMESTAMP(6)

 

SEIANG@seiang11g>

SEIANG@seiang11g>desc t_wjq1_interim

 Name                                                                                                              Null?    Type

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

 OBJECT_ID                                                                                                         NOT NULL NUMBER

 OBJECT_NAME                                                                                                              VARCHAR2(128)

 CREATED                                                                                                                  DATE

 

SEIANG@seiang11g> exec dbms_stats.gather_table_stats(user,'T_WJQ1',cascade => true);

 

PL/SQL procedure successfully completed.

 

Elapsed: 00:00:00.76

 

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

SEIANG@seiang11g>select table_name,partition_name from user_tab_partitions;

 

TABLE_NAME                     PARTITION_NAME

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

T_WJQ1                         P1

T_WJQ1                         P2

T_WJQ1                         P3

T_WJQ1                         P4

 

SEIANG@seiang11g>select constraint_name,constraint_type,table_name from user_constraints;

 

CONSTRAINT_NAME                C TABLE_NAME

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

TMP$$_PK_T_WJQ1_ID0            P T_WJQ1_INTERIM

PK_T_WJQ1_ID                   P T_WJQ1

 

 

之前的实验都是在单表情况下进行的在线重定义操作,但是,在实际的生产环境中,通常涉及到多表关系,例如外键关系表下的重定义,那有该如何处理呢?接下来的案例,作者将介绍多表关系下的在线重定义。



作者:SEian.G(苦练七十二变,笑对八十一难)

您可能感兴趣的文档:

--结束END--

本文标题: Online Redefinition在线重定义(二)--单表复杂案例

本文链接: https://www.lsjlt.com/news/45714.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • sql中year是集函数吗
    否,year 不是 sql 中的聚合函数。year 函数是一个日期函数,用于从给定的日期值中提取年份。它是一个标量函数,返回单个值,而不是值的集合。相反,聚合函数对一组值进行操作并生成一...
    99+
    2024-05-16
    聚合函数
  • sql中between的用法
    sql 中 between 运算符用于检查值是否在指定范围之内,其语法为:select column_name from table_name where colum...
    99+
    2024-05-16
  • sql中update用法
    sql 中的 update 语句用于更新表中的现有数据,通过指定要更新的表、列、值和可选的更新条件来实现,可更新特定行或组行的特定列值。 SQL 中的 UPDATE 语句 什么是 UP...
    99+
    2024-05-16
  • sql中for循环的用法
    sql 中 for 循环可用于遍历结果集,逐行执行操作。语法:for var_name in (select_statement) [loop_statement] end f...
    99+
    2024-05-16
  • sql中any和all的区别
    sql 中 any 和 all 运算符的区别在于:any 检查子查询中是否存在满足条件的行,返回 true 或 false。all 检查子查询中所有行是否都满足条件,返回 true 或 ...
    99+
    2024-05-16
  • sql中exists具体用法
    exists 子查询用于检查外层查询中的行是否存在匹配记录,用法如下:包含在 select 语句的 where 子句中。返回布尔值 true (存在匹配) 或 fal...
    99+
    2024-05-16
  • sql中union用法
    union 运算符在 sql 中用来合并相同结构的表或子查询的结果集,排除重复行。它具有以下用法:合并具有相同列名和数据类型的多个表或子查询的结果集合并为一个。排除结果集中重复...
    99+
    2024-05-16
  • sql中索引的用法
    sql 中索引是一种通过创建数据指针来提高查询性能的技术,主要用于where、order by、join和group by子句。索引类型包括聚集索引、非聚集索引、主键索引、唯一...
    99+
    2024-05-16
    聚合函数
  • sql中nullif怎么用
    sql 中的 nullif() 函数,用于比较两个表达式并返回较小的值,若均为 null 则返回 null,语法为 nullif(expression1, expression2)。可用...
    99+
    2024-05-16
  • sql中decode用法
    decode 函数根据输入表达式值将值转换为另一个值,语法为 decode(expression, value1, result1, value2, result2, ..., defa...
    99+
    2024-05-16
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作