【redefined】在线重定义概览与详细使用(四)
的表是基于empno字段的范围分区表
1.验证admin_emp表是否可以进行基于主键的在线重定义
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE('hr','admin_emp',
DBMS_REDEFINITION.CONS_USE_PK);
END;
/
2.根据需求创建中间表int_admin_emp
CREATE TABLE hr.int_admin_emp
(empno NUMBER(5) PRIMARY KEY,
ename VARCHAR2(15) NOT NULL,
job VARCHAR2(10),
mgr NUMBER(5),
hiredate DATE DEFAULT (sysdate),
sal NUMBER(7,2),
deptno NUMBER(3) NOT NULL,
bonus NUMBER (7,2) DEFAULT(1000))
PARTITION BY RANGE(empno)
(PARTITION emp1000 VALUES LESS THAN (1000) TABLESPACE admin_tbs,
PARTITION emp2000 VALUES LESS THAN (2000) TABLESPACEadmin_tbs2);
3.开始重定义的过程,进行数据的拷贝
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE('hr', 'admin_emp','int_admin_emp',
'empno empno, ename ename, job job, deptno+10 deptno, 0 bonus',
dbms_redefinition.cons_use_pk);
END;
/
4.在中间表int_admin_emp上创建应有的索引、触发器、约束、授权
DECLARE
num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('hr', 'admin_emp','int_admin_emp',
DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
END;
在ignore_errors参数设置为true后,如果发生错误也将跳过忽略,继续执行。例如如果在创建中间表时就在表上建立了主键,则此步骤在向中间表上拷贝原表上的主键时,因有两个主键而报错。但因为ignore_errors参数设置了true后,将会忽略该错误。但是,你也必须执行下一步来确认是否存在其他错误。
5.查询 DBA_REDEFINITION_ERRORS 视图来查看是否有错误发生
SQL> select object_name, base_table_name, ddl_txt from
DBA_REDEFINITION_ERRORS;
OBJECT_NAME BASE_TABLE_NAME DDL_TXT
------------- ---------------- ------------------------------
SYS_C005836 ADMIN_EMP CREATE UNIQUE INDEX "HR"."TMP$
$_SYS_C0058360" ON "HR"."INT_A
DMIN_EMP" ("EMPNO")
SYS_C005836 ADMIN_EMP ALTER TABLE "HR"."INT_ADMIN_EM
P" ADD CONSTRAINT "TMP$$_SYS_C
0058360" PRIMARY KEY
根据查询结果的错误记录,例子中的错误是因为中间表上已经存在主键所导致。虽然此错误可以忽略,但是如果之前在中间表上已经建立了主键,重新定以后的表上的主键和索引的名字将会发生改变不在是原表上的名字,而是仍旧是中间表上的索引和主键的名字。如果之前不在中间表上建立主键约束,我们便可以避免这个无错发生
最好的方法是在建立中间表时同时建立主键,然后使用register_dependent_object过程来注册主键和索引。然后在使用copy_table_dependents来进行其他依赖对象的拷贝。这种方法既避免了错误的发生,保持中间表上有了主键约束的同时,不会使主键的名字发生改变。
如果有其它错误发生,如触发器没有建立成功,可以手动在中间表上建立触发器,然后调用register_dependent_object过程对触发器进行注册。
6.(可选)向int_admin_emp表上进行数据的同步,可以缩短下一步的执行时间
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE('hr', 'admin_emp', 'int_admin_emp');
END;
/
7.完成在线重定义过程
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE('hr', 'admin_emp', 'int_admin_emp');
END;
/
这个阶段中,admin_emp表会被以独占模式锁定一个很小的时间窗口。这个阶段结束后,原表admin_emp将会被重新定义,其所有属性将会和int_admin_emp相同。(其实是int_admin_emp表上有了amdin_emp的数据,然后两个表从定义上互换名字)
8.此时可以删除掉以int_admin_emp命名的表。