Oracle的在线重定义表提供了一种显著增强系统可用性的机制, 在表的在线重定义过程中, 大部分时间对DML操作没有影响, 只有一小段时间里, 这个表以独占模式被锁定, 表以独占模式被锁定的时间是确定的, 和表的大小以及重定义的复杂程度无关.
在线重定义表可用于如下场合:
修改表的存储参数 在同一模式下将表移动到不同的表空间 增加对并行查询的支持 添加或删除分区 重新创建表以减少分片 将堆组织的表改变为索引组织表 添加或删除列
在线重定义表由DBMS_REDEFINITION包完成, 执行这个包需要用户有EXECUTE_CATALOG_ROLE角色以及CREATE/ALTER/DROP/LOCK/SELECT ANY TABLE, CREATE ANY TRIGGER和CREATE ANY INDEX的权限.
表的在线重定义需要执行如下步骤:
1. 选择在线重定义表的类型 在线重定义表分为两种类型:
重定义的第一种方法是使用主键或者伪主键进行重定义。 伪主键是具有NOT NULL约束的列的组合, 在表中, 伪主键必须是唯一的, 也可以理解为伪主键是没有PRIMARY KEY约束的主键. 使用这种方法时, 重定义前后表的(伪)主键列必须相同. 这种方法更好一些, 并且也是默认的.
重定义的第二种方法是使用rowid. 使用这种方法时, 表不能被重定义为索引组织表. 并且, 重定义后的表会有一个隐藏的列M_ROW$$, 重定义表后, 最好删除该列, 或将该列标识为UNUSED.
2. 调用DBMS_REDEFINITION.CAN_REDEF_TABLE()过程验证这个表可被重定义 参数OPTIONS_FLAG指定要使用的重定义的方法. 如果这个表不可以被在线重定义, 这个过程会指明原因.
3. 创建一个中间表 这个中间表和将被重定义的表在同一schema下, 其定义与重定义后的表相同.
4. 调用DBMS_REDEFINITION.START_REDEF_TABLE()过程 参数如下: 被重定义的表, 中间表, 列影射关系, 重定义方法, 用语排序的列, 指定ORDER BY列. 5. 在中间表上创建(克隆)依赖对象, 包括触发器, 索引, 授权, 约束. 可以使用COPY_TABLE_DEPENDENTS过程或者手工方式创建这些依赖对象.
6. 执行DBMS_REDEFINITION.START_REDEF_TABLE()过程, 这个过程是可选的, 执行这一过程, 将会把在原始表上进行的DML操作在中间表上执行, 执行这一过程将减少在下一步骤执行的时间. 7. 执行 DBMS_REDEFINITION.FINISH_REDEF_TABLE过程完成表的重定义. 在这个过程中, 将被重定义的表被以独占模式锁定, 这个过程与表中的数据无关. 但是FINISH_REDEF_TABLE将回等待所有依赖的DML操作完成, 才开始重定义操作.
8. 可选, 删除rowid方式建立的隐藏列M_ROW$$, 或者将该列设置为unused.
如果由于某些原因希望终止在线重定义表, 可使用DBMS_REDEFINITION.ABORT_REDEF_TABLE()过程.
在线重定义表的结果:
原始表被重定义为中间表的属性和功能.
在执行START_REDEF_TABLE()和执行FINISH_REDEF_TABLE()期间, 定义在中间表上的触发器, 授权, 索引以及约束将被定义在重定义后的表上. 引用中间表的参考约束将引用重定义后的表, 并且设置为enabled.
定义在原始表上的触发器, 授权, 索引以及约束将被定义在中间表上, 删除中间表时, 这些对象将被删除. 引用原始表的参考性约束, 将引用中间表, 并被设置为disable. 定义才原始表上的PL/SQL过程和游标, 将在下次使用时将重新验证. |