在9i的时候,表空间的迁移使用EXP/IMP来实现。在10g中,除了使用EXP/IMP之外,还可以使用数据泵EXPDP/IMPDP,以及RMAN的命令TRANSPORT TABLESPACE命令,除此之外,还可以通过PL/SQL包DBMS_STREAMS_TABLESPACE_ADM来实现。
这一篇介绍DETACH_TABLESPACES过程。
利用PLSQL实现表空间的迁移(一):http://yangtingkun.itpub.net/post/468/484859
利用PLSQL实现表空间的迁移(二):http://yangtingkun.itpub.net/post/468/485388
利用PLSQL实现表空间的迁移(三):http://yangtingkun.itpub.net/post/468/491799
利用PLSQL实现表空间的迁移(四):http://yangtingkun.itpub.net/post/468/491878
在前面几篇文章中,分别介绍了CLONE, ATTACH以及PULL对应的过程,这里最后描述一下DETACH过程。DETACH和CLONE、PULL以及EXPDP/EXP的实现上都有所区别,执行DETACH过程后,需要传输的数据文件和对应的dmp文件都准备完毕,而对应的表空间也将从数据库中被删除。
目标数据库和当前数据库具有相同的数据库版本、数据块大小、以及字符集,这里就不再重复检查了。需要检查的是,被迁移表空间是否是自包含的。
SQL> SELECT DISTINCT OWNER
2 FROM DBA_SEGMENTS
3 WHERE TABLESPACE_NAME = 'ZHEJIANG';
OWNER
------------------------------
ZHEJIANG_OPERATOR
ZHEJIANG
ZHEJIANG_KHD
SQL> SELECT DISTINCT TABLESPACE_NAME
2 FROM DBA_SEGMENTS
3 WHERE OWNER IN ('ZHEJIANG', 'ZHEJIANG_OPERATOR', 'ZHEJIANG_KHD');
TABLESPACE_NAME
------------------------------
ZHEJIANG
SQL> SELECT FILE_NAME
2 FROM DBA_DATA_FILES
3 WHERE TABLESPACE_NAME = 'ZHEJIANG';
FILE_NAME
------------------------------------------------------------------------------------------------------------------------
/dev/vx/rdsk/datadg/tradedb_zhejiang_1_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_2_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_3_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_4_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_5_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_6_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_7_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_8_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_9_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_10_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_11_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_12_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_13_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_14_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_15_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_16_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_17_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_18_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_19_4g
/dev/vx/rdsk/datadg/tradedb_zhejiang_20_4g
已选择20行。
SQL> EXEC DBMS_TTS.TRANSPORT_SET_CHECK('ZHEJIANG')
PL/SQL 过程已成功完成。
SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
未选定行
表空间已经处于只读状态,就不用额外进行设置了:
SQL> SELECT TABLESPACE_NAME, STATUS
2 FROM DBA_TABLESPACES
3 WHERE TABLESPACE_NAME = 'ZHEJIANG';
TABLESPACE_NAME STATUS
------------------------------ ---------
ZHEJIANG READ ONLY
建立DETACH_TABLESPACES过程所需的目录:
SQL> CREATE OR REPLACE DIRECTORY D_READFILE AS '/dev/vx/rdsk/datadg';
目录已创建。
SQL> CREATE OR REPLACE DIRECTORY D_WRITEFILE AS '/data/transport_zhejiang';
目录已创建。
下面就可以执行DETACH_TABLESPACES过程了,需要注意,这个过程的输入参数包括了索引组织表类型和记录,因此需要通过建立一个PL/SQL匿名块来完成调用,注意输入参数变量的声明需要用DBMS_STREAMS_TABLESPACE_ADM包中的类型进行声明,否则调用会报错:
SQL> SET SERVEROUT ON SIZE 1000000
SQL> DECLARE
2 V_JOB_NAME VARCHAR2(30) := 'MY_DETACH_TABLESPACES';
3 V_TABLESPACE_NAME DBMS_STREAMS_TABLESPACE_ADM.TABLESPACE_SET;
4 V_DUMPFILE DBMS_STREAMS_TABLESPACE_ADM.FILE;
5 V_LOGFILE DBMS_STREAMS_TABLESPACE_ADM.FILE;
6 V_DATAFILES DBMS_STREAMS_TABLESPACE_ADM.FILE_SET;
7 BEGIN
8 V_TABLESPACE_NAME(1) := 'ZHEJIANG';
9 V_DUMPFILE.DIRECTORY_OBJECT := 'D_WRITEFILE';
10 V_DUMPFILE.FILE_NAME := 'zhejiang_091217.dp';
11 V_LOGFILE.DIRECTORY_OBJECT := 'D_WRITEFILE';
12 V_LOGFILE.FILE_NAME := 'zhejiang_091217.log';
13 DBMS_STREAMS_TABLESPACE_ADM.DETACH_TABLESPACES(V_JOB_NAME,
14 V_TABLESPACE_NAME,
15 V_DUMPFILE,
16 V_LOGFILE,
17 V_DATAFILES);
18 FOR I IN 1..V_DATAFILES.COUNT LOOP
19 DBMS_OUTPUT.PUT_LINE(V_DATAFILES(I).FILE_NAME);
20 END LOOP;
21 END;
22 /
DECLARE
*
第 1 行出现错误:
ORA-02449: 表中的唯一/主键被外键引用
ORA-06512: 在 "SYS.DBMS_STREAMS_TABLESPACE_ADM", line 885
ORA-06512: 在 line 13
执行过程报错了,用了几次的DBMS_STREAMS_TABLESPACE_ADM包,似乎只有第一次运行PULL_SIMPLE_TABLESPACE过程时没有报错,剩下的几次虽然也都成功了,但是多少都会出现一些错误。
不过这次的错误多少有些奇怪,看错误信息似乎和迁移表空间的关系不大,倒是和前一段时间删除表空间时碰到的一个bug有些相似。
检查输出的LOG文件信息:
bash-3.00$ more zhejiang_091217.log
启动 "SYS"."MY_DETACH_TABLESPACES":
处理对象类型 TRANSPORTABLE_EXPORT/PLUGTS_BLK
处理对象类型 TRANSPORTABLE_EXPORT/TABLE
处理对象类型 TRANSPORTABLE_EXPORT/GRANT/OWNER_GRANT/OBJECT_GRANT
处理对象类型 TRANSPORTABLE_EXPORT/INDEX
处理对象类型 TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINT
处理对象类型 TRANSPORTABLE_EXPORT/INDEX_STATISTICS
处理对象类型 TRANSPORTABLE_EXPORT/COMMENT
处理对象类型 TRANSPORTABLE_EXPORT/CONSTRAINT/REF_CONSTRAINT
处理对象类型 TRANSPORTABLE_EXPORT/TRIGGER
处理对象类型 TRANSPORTABLE_EXPORT/INDEX/FUNCTIONAL_AND_BITMAP/INDEX
处理对象类型 TRANSPORTABLE_EXPORT/INDEX/STATISTICS/FUNCTIONAL_AND_BITMAP/INDEX_STATISTICS
处理对象类型 TRANSPORTABLE_EXPORT/TABLE_STATISTICS
处理对象类型 TRANSPORTABLE_EXPORT/POST_TABLE_ACTION
处理对象类型 TRANSPORTABLE_EXPORT/MATERIALIZED_VIEW_LOG
处理对象类型 TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
已成功加载/卸载了主表 "SYS"."MY_DETACH_TABLESPACES"
******************************************************************************
SYS.MY_DETACH_TABLESPACES 的转储文件集为:
/data/transport_zhejiang/zhejiang_091217.dp
作业 "SYS"."MY_DETACH_TABLESPACES" 已于 18:11:02 成功完成
从这里可以看到,传输表空间的导出工作已经顺利完成。
检查alert文件:
bash-3.00$ tail -15 $ORACLE_BASE/admin/tradedb/bdump/alert_tradedb1.log
ALTER SYSTEM SET service_names='tradedb.us.oracle.com','SYS$SYS.KUPC$C_1_20091217180920.TRADEDB.US.ORACLE.COM' SCOPE=MEMORY SID='tradedb1';
Thu Dec 17 18:09:23 2009
ALTER SYSTEM SET service_names='SYS$SYS.KUPC$C_1_20091217180920.TRADEDB.US.ORACLE.COM','tradedb.us.oracle.com','SYS$SYS.KUPC$S_1_20091217180920.TRADEDB.US.ORACLE.COM' SCOPE=MEMORY SID='tradedb1';
kupprdp: master process DM00 started with pid=74, OS id=4415
to execute - SYS.KUPM$MCP.MAIN('MY_DETACH_TABLESPACES', 'SYS', 'KUPC$C_1_20091217180920', 'KUPC$S_1_20091217180920', 0);
kupprdp: worker process DW01 started with worker id=1, pid=39, OS id=4477
to execute - SYS.KUPW$WORKER.MAIN('MY_DETACH_TABLESPACES', 'SYS');
Thu Dec 17 18:11:23 2009
ALTER SYSTEM SET service_names='SYS$SYS.KUPC$S_1_20091217180920.TRADEDB.US.ORACLE.COM','tradedb.us.oracle.com' SCOPE=MEMORY SID='tradedb1';
Thu Dec 17 18:11:23 2009
ALTER SYSTEM SET service_names='tradedb.us.oracle.com' SCOPE=MEMORY SID='tradedb1';
Thu Dec 17 18:11:24 2009
DROP TABLESPACE "ZHEJIANG" INCLUDING CONTENTS
Thu Dec 17 18:11:29 2009
ORA-2449 signalled during: DROP TABLESPACE "ZHEJIANG" INCLUDING CONTENTS...
显然这个错误是删除表空间时碰到的,而传输表空间的操作已经完成了。引发这个错误的原因在文章http://yangtingkun.itpub.net/post/468/492354中已经进行了描述。
和CLONE_TABLESPACES过程不同,表空间传输的源数据生成后,并不会拷贝一份数据文件,而是将表空间删除,数据文件就保留在当前的位置上。
SQL> DROP TABLESPACE ZHEJIANG INCLUDING CONTENTS CASCADE CONSTRAINTS;
表空间已删除。
添加CASCADE CONSTRAINTS语句,手工方式删除表空间后,现在数据库的状态和执行DETACH_TABLESPACES操作后保持一致。
至此DETACH_TABLESPACES过程执行完成。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-622741/ ,如需转载,请注明出处,否则将追究法律责任。