「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」
一、DBMS_REDEFINITION(在线重定义)
参考MOS文档:_How To Partition Existing Table Using DBMS_REDEFINITION (Doc ID 472449.1) _
支持的数据库版本***:Oracle Database - Enterprise Edition - Version 9.2.0.4 and later***
在线重定义是通过 物化视图 实现的。
使用在线重定义的一些限制条件:
1、必须有足够的表空间来容纳表的两倍数据量。
2、主键列不能被修改。
3、表必须有主键。
4、必须在同一个用户下进行在线重定义。
5、SYS和SYSTEM用户下的表无法进行在线重定义。
6、在线重定义无法采用nologging。
7、如果中间表有新增列,则不能有NOT NULL约束
DBMS_REDEFINITION包:
- ABSORT_REDEF_TABLE:清理重定义的错误和中止重定义;
- CAN_REDEF_TABLE:检查表是否可以进行重定义,存储过程执行成功代表可以进行重定义;
- COPY_TABLE_DEPENDENTS:同步索引和依赖的对象(包括索引、约束、触发器、权限等);
- FINISH_REDEF_TABLE:完成在线重定义;
- REGISTER_DEPENDENTS_OBJECTS:注册依赖的对象,如索引、约束、触发器等;
- START_REDEF_TABLE:开始在线重定义;
- SYNC_INTERIM_TABLE:增量同步数据;
- UNREGISTER_DEPENDENT_OBJECT:不注册依赖的对象,如索引、约束、触发器等;
1 | sql复制代码CREATE OR REPLACE PACKAGE SYS.dbms_redefinition AUTHID CURRENT_USER IS |
二、在线重定义表的步骤
**1.**创建未分区的表,如果存在,就不需要操作。
1 | sql复制代码--前置准备:创建用户,表空间,授权用户。 |
2.确认表是否存在主键,表空间是否足够,收集表统计信息。
1 | sql复制代码--查看表主键 |
3.调用DBMS_REDEFINITION.CAN_REDEF_TABLE()过程,确认表是否满足重定义的条件。
1 | sql复制代码SQL> EXEC Dbms_Redefinition.can_redef_table('PAR', 'STUDENT'); |
4.在用一个用户中建立一个空的中间表,根据重定义后你期望得到的结构建立中间表。比如:采用分区表(间隔分区),增加了COLUMN等。
在中间表上建立触发器、索引和约束,并进行相应的授权。任何包含中间表的完整性约束应将状态置为disabled。(此步骤也可以放在同步数据后操作)
1 | sql复制代码--创建间隔分区(增加列s_phone) |
5.调用DBMS_REDEFINITION.START_REDEF_TABLE()过程,并提供下列参数:被重定义的表的名称、中间表的名称、列的映射规则、重定义方法。
如果映射方法没有提供,则认为所有包括在中间表中的列用于表的重定义。如果给出了映射方法,则只考虑映射方法中给出的列。如果没有给出重定义方法,则默认使用主键方式。
1 | sql复制代码SQL> BEGIN |
6.(可选)在创建索引之前将新表与临时名称同步。
Notes:如果在执行DBMS_REDEFINITION.START_REDEF_TABLE()过程和执行DBMS_REDEFINITION.FINISH_REDEF_TABLE()过程直接在重定义表上执行了大量的DML操作,那么可以选择执行一次或多次的SYNC_INTERIM_TABLE()过程,此操作可以减少最后一步执行FINISH_REDEF_TABLE()过程时的锁定时间。
1 | sql复制代码--模拟业务不停,DML表数据写入 |
7.执行DBMS_REDEFINITION.FINISH_REDEF_TABLE()过程完成表的重定义。这个过程中,原始表会被独占模式锁定一小段时间,具体时间和表的数据量有关。
执行完FINISH_REDEF_TABLE()过程后,原始表重定义后具有了中间表的属性、索引、约束、授权和触发器。中间表上disabled的约束在原始表上处于enabled状态。
1 | sql复制代码--收集par table的统计信息 |
此时,临时表(及其索引)已成为“真实”表,并且它们的名称已在名称词典中切换。
8.重命名所有约束和索引以匹配原始名称
1 | sql复制代码--drop中间表或者rename原来的约束 |
本文转载自: 掘金