http://boylook.itpub.net/post/43144/520542

Oracle9i之前,表数据的整理是通过 alter table XXX move [tablespace XX]进行的。如果表非常大,IO又不快的时候,move的过程可能相当漫长,不能算是HA特性。因此在HA的在线维护中,基本不会利用move来重组大型表,而且move后的表需要重建索引。而在9i引入的dbms_redefinition。该过程的内部原理其实就是采用了MV的机制,类似在原表建立一个prebuilt的MV然后一直增量刷新到数据差别最小。Oracle在很小的停顿中,完成最后一点的增量同步,达到完全同步后,把原表与新表换个名字,由于换名操作仅仅是数据字典,所以最终切换时间非常短。
--首先建立一个用来测试外键约束的表test_refed

SQL> create table test_refed(id number primary key);

Table created.

SQL> insert into test_refed select rownum from dba_objects where rownum<10001;

10000 rows created.

SQL> commit;

Commit complete.

--创建我们准备修改表定义的表test,未分区

SQL> create table test(id number,fid number);

Table created.

SQL> insert into test select rownum,rownum from dba_objects where rownum<1001;

1000 rows created.

SQL> commit;

Commit complete.

--添加主键约束以及外键约束,并在外键上建立索引

SQL> alter table test add constraint pk_test primary key(id);

Table altered.

SQL> alter table test add constraint fk_test_refed_id foreign key(fid) references test_refed(id);

Table altered.

SQL> create index idx_test_fid on test(fid);

Index created.

--创建基于test表的触发器

SQL> create trigger tr_test
2 before insert on test for each row
3 begin
4 null;
5 end;
6 /

Trigger created.

--准备工作:调用dbms_redefinition.can_redef_table来验证boylook.test是否可以在线重定义。一般情况没有主键等会报错。
SQL> begin
2 dbms_redefinition.can_redef_table('BOYLOOK','TEST');
3 end;
4 /

PL/SQL procedure successfully completed.

--创建需要重新定义的过渡表inter_test,这是一个分区表,以后将把原表所有数据在线转移到该表当中。注意到,该表比原表test还多一个字段c

SQL> create table inter_test(id number,fid number,c number)
2 partition by range(id)
3 (partition p1 values less than(400),
4 partition p2 values less than(800),
5 partition p3 values less than(maxvalue));

Table created.

SQL> alter table inter_test add constraint pk_inter_test primary key(id);

Table altered.

--执行在线重定义
注:调用这个存储过程需要create/alter/drop/lock/select any table权限

SQL> exec dbms_redefinition.start_redef_table('BOYLOOK','TEST','INTER_TEST','id id,fid fid,0 c');

PL/SQL procedure successfully completed.

--验证数据是否刷了过去
SQL> select count(*) from inter_test;

COUNT(*)
----------
1000

--继续对原表test进行操作
SQL> insert into test select rownum+1000,rownum+1000 from dba_objects where rownum <=24;

24 rows created.

SQL> commit;

Commit complete.

SQL> select count(*) from test;

COUNT(*)
----------
1024

SQL> select count(*) from inter_test;

COUNT(*)
----------
1000

--执行表同步
注:这一步不是必须的,但是对于比较大的表,中间运行增量同步有助于减少切换时间。

SQL> exec dbms_redefinition.sync_interim_table('BOYLOOK','TEST','INTER_TEST');

PL/SQL procedure successfully completed.

--我们发现数据同步的过来
SQL> select count(*) from inter_test;

COUNT(*)
----------
1024

--将原表test的约束,索引,触发器迁移过来
注:这里最好要检查一下授权。检查test以前的权限,并给中间表inter_test赋予同样的权限。否则原表的权限不会转移到新表
SQL> alter table inter_test add constraint fk_inter_refed_id foreign key(fid) references test_refed(id);

Table altered.

SQL> create index idx_inter_test_fid on inter_test(fid);

Index created.

SQL> create or replace trigger tr_inter_test
2 before insert on inter_test for each row
3 begin
4 null;
5 end;
6 /

Trigger created.

--执行重定义完成的过程。Oracle完成了表test到表inter_test的换名工作,只是所有的约束,索引或触发器名称还是保持着原来表上面的名称

SQL> exec dbms_redefinition.finish_redef_table('BOYLOOK','TEST','INTER_TEST');

PL/SQL procedure successfully completed.

SQL> desc test;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
FID NUMBER
C NUMBER

SQL> desc inter_test;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
FID NUMBER

SQL> select table_name,partition_name from user_tab_partitions where table_name ='TEST';

TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
TEST P1
TEST P2
TEST P3

SQL> select table_name,constraint_name,status from user_constraints where table_name in('TEST','INTER_TEST');

TABLE_NAME CONSTRAINT_NAME STATUS
------------------------------ ------------------------------ --------
INTER_TEST PK_TEST ENABLED
INTER_TEST FK_TEST_REFED_ID DISABLED
TEST PK_INTER_TEST ENABLED
TEST FK_INTER_REFED_ID ENABLED

SQL> select table_name,index_name from user_indexes where table_name in('TEST','INTER_TEST');

TABLE_NAME INDEX_NAME
------------------------------ ------------------------------
TEST PK_INTER_TEST
TEST IDX_INTER_TEST_FID
INTER_TEST PK_TEST
INTER_TEST IDX_TEST_FID

SQL> select table_name,trigger_name from user_triggers where table_name in('TEST','INTER_TEST');

TABLE_NAME TRIGGER_NAME
------------------------------ ------------------------------
TEST TR_INTER_TEST
INTER_TEST TR_TEST

SQL> select * from test where rownum <=10;

ID FID C
---------- ---------- ----------
1 1 0
2 2 0
3 3 0
4 4 0
5 5 0
6 6 0
7 7 0
8 8 0
9 9 0
10 10 0

10 rows selected.

--删除过渡表了,收工。这时也可以考虑修改索引,约束触发器的名称与原来保持一致

SQL> drop table inter_test cascade constraints purge;

Table dropped.

转载于:https://blog.51cto.com/boylook/1298615

Oracle在线重定义相关推荐

  1. oracle在线重定义(一)

    一.废话几句: 关于pd12导出图像, 首先ctrl+A全选 然后:edit->Export Image-->emf格式为默认,实则任选就OK了: 下午时隔4个月再次画ER图,相对的感觉要 ...

  2. 【转】Oracle在线重定义DBMS_REDEFINITION 普通表—分区表

    实验环境:RHEL 6.4 + Oracle 11.2.0.3 实验:在线重定义 普通表 为 分区表,包括主键对应的索引都改造为分区索引. 1,构造普通表t_objects conn test1/te ...

  3. linux下出现重定义,Oracle Online Redefinition在线重定义

    在线重定义特性进行数据表Online的结构变动操作.本篇我们从一个较复杂的案例出发,讨论复杂变化情况下如何进行Online Redefinition,以及dbms_redefinition包各个关键方 ...

  4. Oracle Online Redefinition在线重定义(下)

    在之前的文章中,我们看到了如何处理单表在线重定义过程.本篇我们来看一下如何进行关联表的重定义过程. 4.外键关系表重定义 我们先创建出实验数据表. SQL> create table t_mas ...

  5. Oracle 11gR2 在线重定义(online redefinition)

    在Oracle9i出现之前,你只能通过MOVE或导出和导入的方式来进行表的重定义,因此表重定义的过程可能相当漫长或者说是一个离线过程,在此期间应用程序对该表的操作将失败.除了这个,如果用exp,我们也 ...

  6. ORACLE 普通表转换成分区表(在线重定义)

    在一个高可用系统中,如果需要改变一个表的定义是一件比较棘手的问题,尤其是对于7×24系统.Oracle提供的基本语法基本可以满足一般性修改,但是对于把普通堆表改为分区表,把索引组织表修改为堆表等操作就 ...

  7. oracle 10g在线重定义新特性——关联对象自动重命名(二)

    9i的在线重定义存在一个问题,执行完在线重定义后,表的名称虽然保持不变,但是索引.约束.触发器等关联对象的名称会发生变化,有时候这会带来一定的问题,而要在事后手工修改,会比较麻烦. 10g的在线重定义 ...

  8. cmds在线重定义增加列

    --输出信息采用缩排或换行格式化 EXEC DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, 'PRETTY', T ...

  9. 在线重定义的补充测试

    在很多时候,我们都是需要保持业务的可持续性,尽管说DDL的过程持续时间很短,但是在线业务出现,就会阻塞DML,导致业务访问中断,事务收到影响,所以在有些场景下,高可用的需求可能比性能的需求优先级还要高 ...

最新文章

  1. MySQLWorkbench注释
  2. 终端仿真程序_SecureCRT for mac(终端SSH工具)
  3. mysql shell命令和作用_MySQL的一些功能实用的Linux shell脚本分享
  4. 小猪cms之怎样查询绑定的微网站模板
  5. 罗技 GHUB驱动的官方下载网址
  6. 网页复制的文本粘贴到Word中有背景色要怎么去掉
  7. 小狼毫0.14 五笔拼音混输 Rime14
  8. 12月18日科技资讯|支付宝、微信回应3D面具破解人脸识别;ofo 否认「发币」;Kafka 2.4.0 发布
  9. 文件上传图片放大缩小进行截图上传
  10. 电商订单批量导入API接口功能
  11. esp32拍照传输到手机android,ESP32 之 esp32-cam wifi拍照传图系统2
  12. 请列举至少3款B端互联网产品,从产品定位、目标用户需求、竞争优势等方面分析这些产品
  13. [STC系列单片机/51单片机]软件延时计算方法详解
  14. 关于迅盘Turbo Memory的ReadyDrive功能被禁用的思考
  15. 多目标优化(一):Pareto理论相关概念解析
  16. 2019自结前端面试小册
  17. 视频质量分析工具介绍
  18. 2只继电器控制三相电机正反转
  19. Fences4 桌面整理好帮手 让你的桌面整洁美观
  20. Android 静默安装和智能安装的实现方法

热门文章

  1. Bootstrap-table学习笔记(二)——前后端分页模糊查询
  2. Swift 3.1 的一些新特性
  3. Android 面试题(转)
  4. 【转】Android兼容性测试CTS --环境搭建、测试执行、结果分析
  5. resize函数_每日一题手写函数防抖与节流
  6. VS 2017显示“高级保存选项”命令操作方法
  7. 20155335俞昆 2017-2018-1 《信息安全系统设计》第9周学习总结
  8. 兼容性好的CSS字体投影
  9. » 欄位太小以致於無法接受您試圖加入的資料數量
  10. ScottGu之博客翻译-LINQ to SQL第三部分,查询数据库 (Part 3 - Querying our Database)