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
/
dbms_redefinition方式普通表改造分区表的更多相关文章
- 使用DBMS_REDEFINITION在线切换普通表到分区表
		随着数据库数据量的不断增长,有些表须要由普通的堆表转换为分区表的模式.有几种不同的方法来对此进行操作.诸如导出表数据,然后创建分区表再导入数据到分区表.使用EXCHANGE PARTITION方式来转 ... 
- Oracle 分区表的新增、修改、删除、合并。普通表转分区表方法
		一. 分区表理论知识 Oracle提供了分区技术以支持VLDB(Very Large DataBase).分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中.分区完全对应用透明. Orac ... 
- oracle_分区表的新增、修改、删除、合并。普通表转分区表方法
		一. 分区表理论知识Oracle提供了分区技术以支持VLDB(Very Large DataBase).分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中.分区完全对应用透明. Oracl ... 
- oracle表分区以及普表转分区表(转)
		概述 Oracle的表分区功能通过改善可管理性.性能和可用性,从而为各式应用程序带来了极大的好处.通常,分区可以使某些查询以及维护操作的性能大大提高.此外,分区还可以极大简化常见的管理任务,分区是构建 ... 
- Oracle 将普通表转换为分区表
		DB:11.2.0.30 将普通表转换为区分表 一.利用原表重建分区表SQL>create table yoon ( id number primary key ,time date ); Ta ... 
- mysql分表与分区表
		mysql分表与分区表 转自:http://blog.51yip.com/mysql/949.html 一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具 ... 
- 一起学Hive——创建内部表、外部表、分区表和分桶表及导入数据
		Hive本身并不存储数据,而是将数据存储在Hadoop的HDFS中,表名对应HDFS中的目录/文件.根据数据的不同存储方式,将Hive表分为外部表.内部表.分区表和分桶表四种数据模型.每种数据模型各有 ... 
- 通过替换frm文件方式修改表结构
		版本:5.6.16 在自己的虚拟环境中,测试创建一个表,表结构如下:mysql> drop table yoon_temp;Query OK, 0 rows affected (0.09 sec ... 
- ajax无刷新方式收集表单并提交表单
		ajax无刷新方式收集表单有两种方式, 一个是使用html5的FormData.一个是传统的方式. 一,FormData,在主流的浏览器中可以用,IE不好用啊. 另外,FormData使用有两个条件, ... 
随机推荐
- js 策略模式  实现表单验证
			策略模式 简单点说就是:实现目标的方式有很多种,你可以根据自己身情况选一个方法来实现目标. 所以至少有2个对象 . 一个是策略类,一个是环境类(上下文). 然后自己就可以根据上下文选择不同的策略来执 ... 
- js 每到达5次换一行
			function getYourString(s) { var res = ''; var length = s.length; for (var i = 0, j = 1; i < lengt ... 
- 小tips:JS操作数组的slice()与splice()方法
			slice(start, end) slice()方法返回从参数指定位置开始到当前数组末尾的所有项.如果有两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项. var colors = ... 
- HDU 3032 Nim or not Nim?(Multi-Nim)
			Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ... 
- cf932E. Team Work(第二类斯特灵数 组合数)
			题意 题目链接 Sol 这篇题解写的非常详细 首先要知道第二类斯特灵数的一个性质 \[m^n = \sum_{i = 0}^m C_{n}^i S(n, i) i!\] 证明可以考虑组合意义:\(m^ ... 
- 洛谷P3245 [HNOI2016]大数(莫队)
			题意 题目链接 Sol 莫队板子题.. 维护出每个位置开始的字符串\(mod P\)的结果,记为\(S_i\) 两个位置\(l, r\)满足条件当且仅当\(S_l - S_r = 0\),也就是\(S ... 
- angularJS中控制器和作用范围
			$scope是$rootScope的子作用域控制对象,$rootScope的id为1,其他的为2,3,4... 不同的控制器之间,所对应的作用域控制对象$scope,之间是相互隔离的,如果要共享数据, ... 
- 极简】如何在服务器上安装SSL证书?
			本文适合任何人了解,图形化操作.下面以腾讯云为例,并且服务器(linux)也安装了宝塔面板. 1.登陆腾讯云账号进入控制台,找到SSL的产品 2.按要求申请并填写表单,记住私钥密码 3.提交后,待腾讯 ... 
- Loadrunner 脚本开发-利用web_submit_data函数实现POST请求
			脚本开发-利用web_submit_data函数实现POST请求 by:授客 QQ:1033553122 概述 web_link()和web_url()函数都是页面访问型函数,实现HTTP请求中的 ... 
- 你不可不知的Java引用类型之——虚引用
			定义 虚引用是使用PhantomReference创建的引用,虚引用也称为幽灵引用或者幻影引用,是所有引用类型中最弱的一个.一个对象是否有虚引用的存在,完全不会对其生命周期构成影响,也无法通过虚引用获 ... 
