IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

利用DBMS_REDEFINITION在线重定义表

Incessant 2009-10-11 22:21:46 累计浏览 2,233 次
本机暂存

    7*24的业务运营系统中,对一个表进行在线重定义将是很棘手的事,因为业务实时的在对这个表进行进行插入,删除修改等操作,那么是否可以在线重定义表呢,Oracle9i提供了在线重定义表包(DBMS_REDEFINITION),在修改表结构的同时可以进行DML操作。

    1.构造原始数据表

    SQL> create table red_test --原始表,需要对这个表进行在线重定义

     2 as

     3 select te_seq.nextval as id ,t.owner,t.object_name,10 as tvalue from dba_objects t ;

    Table created

    SQL> alter table RED_TEST --增加主键

     2 add constraint pri_redtest primary key (id);

    Table altered

    SQL> create index idc_retest_owner on red_test(owner) ;

    Index created

    需求:把red_test进行在线重定义,把tvuale字段更改为sal字段,并且sal=tvalue*10

    2.验证是否可以在线重定义

    SQL> EXEC Dbms_Redefinition.Can_Redef_Table(\'etl\', \'red_test\',DBMS_REDEFINITION.CONS_USE_PK);

    PL/SQL procedure successfully completed

    3.建立中间表

    SQL> CREATE TABLE RED_TEST_MIDDLE AS

     2 SELECT id,owner,object_name,tvalue as sal FROM red_test WHERE 1=2;

    Table created

    SQL> alter table RED_TEST_MIDDLE

     2 add constraint pri_redtest123 primary key (id);

    Table altered

    4.进行在线重定义

    SQL> EXEC Dbms_Redefinition.Start_Redef_Table( \'ETL\',\'RED_TEST\',\'RED_TEST_MIDDLE\',\'ID

     ID, OWNER OWNER, OBJECT_NAME OBJECT_NAME,TVALUE*10 SAL\');

    PL/SQL procedure successfully completed

    6.同步中间表,主要是同步重定义过程中变化的数据

    SQL> EXEC dbms_redefinition.sync_interim_table(\'ETL\', \'RED_TEST\', \'RED_TEST_MIDDLE\');

    PL/SQL procedure successfully completed

    7.测试在原始表继续插入是否还会同步

    SQL> insert into RED_TEST select te_seq.nextval as id ,t.owner,t.object_name,999 from dba_objects t ;

    34193 rows inserted

    SQL> commit;

    Commit complete

    --重定义过程原始表发生dml的数据会保留MV log,这就是为什么原始表要有主键的原因,当然也可以利用rowid

    SQL> select count(*) from Mlog$_red_test;--原始产生的dml操作会记录在mv log

     COUNT(*)

    ----------

     34193

    8.完成重定义

    SQL> EXEC Dbms_Redefinition.Finish_Redef_Table( \'ETL\', \'RED_TEST\', \'RED_TEST_MIDDLE\');

    PL/SQL procedure successfully completed

    9.检查是否完成了重定义

    SQL> select ix.table_name,ix.index_name from user_indexes ix where ix.table_name=\'RED_TEST\';

    TABLE_NAME INDEX_NAME

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

    RED_TEST PRI_REDTEST123

    SQL> select ix.table_name,ix.index_name from user_indexes ix where ix.table_name=\'RED_TEST_MIDDLE\' ;

    TABLE_NAME INDEX_NAME

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

    RED_TEST_MIDDLE IDC_RETEST_OWNER

    RED_TEST_MIDDLE PRI_REDTEST

    --比较一下中间表和原始表的索引,发觉仅仅是同步了数据,索引并不能同步过去,所以在正式环境中,应该先建立索引在完成重定义,建立索引可以放在第5步来做

    10.删除中间表

    SQL> drop table RED_TEST_MIDDLE ;

    Table dropped

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

    一般会有这个需求,需要将在线大表(5G以上)更改为分区表,Dbms_Redefinition在线重定义非常慢,可能需要好几个小时,大表又是实时的业务操作,这就存在很大的失败风险。有朋友曾经在线重定义过程中失败导致业务瘫痪,建议还是少用,或是不用,知道有这么回事就可以了。

    个人觉得如下步骤比较保险,但是需要停机

    a) export the table

    b) create a new empty table that has the partition definition on it

    c) import the table with IGNORE=Y

    参考:

    http://orafaq.com/node/4

    http://asktom.oracle.com/pls/asktom/f?p=100:11:1619565279119772::::P11_QUESTION_ID:4636779130376

    http://roujiaweize.spaces.live.com/blog/cns!9745F14B4AEB3B72!818.entry

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. Oracle MTS模式下 进程地址与会话信息 (累计阅读 14,406)
  2. 那些在11gR2中可能惹祸的新特性,一张列表帮助你摆脱升级11gR2带来的烦恼 (累计阅读 6,878)
  3. 性能测试工具sysbench简介 (累计阅读 6,025)
  4. 大于2GB的Listener.log和运行超过198天的主机上的Oracle实例 (累计阅读 5,861)
  5. 仅仅只备份是不够的 (累计阅读 5,823)
  6. Oracle Database 12c 新特性 - Native Top N 查询 (累计阅读 5,749)
  7. ORACLE最大可以存储多少数据量 (累计阅读 5,726)
  8. Oracle DBA的学习进阶成长树-从初出茅庐到高瞻远瞩 (累计阅读 5,600)
  9. 老托的Oracle 数据库Patch概念性小常识 (累计阅读 5,546)
  10. 查看oracle数据库用户下的所有空表 (累计阅读 5,502)