在9i的时候,表空间的迁移使用EXP/IMP来实现。在10g中,除了使用EXP/IMP之外,还可以使用数据泵EXPDP/IMPDP,以及RMAN的命令TRANSPORT TABLESPACE命令,除此之外,还可以通过PL/SQL包DBMS_STREAMS_TABLESPACE_ADM来实现。
这一篇介绍PULL_TABLESPACES过程。
利用PLSQL实现表空间的迁移(一):http://yangtingkun.itpub.net/post/468/484859
前文已经介绍过Oracle的DBMS_STREAMS_TABLESPACE_ADM包提供了8个过程:ATTACH_TABLESPACES、ATTACH_SIMPLE_TABLESPACE、CLONE_TABLESPACES、CLONE_SIMPLE_TABLESPACE、DETACH_TABLESPACES、DETACH_SIMPLE_TABLESPACE、PULL_TABLESPACES、PULL_SIMPLE_TABLESPACE。
其中PULL过程实际上包含了CLONE以及ATTACH两个过程,其中还包括了DBMS_FILE_TRANSFER包的调用,使得在目标数据库执行一个命令就完成表空间迁移的所有的操作。
这次要迁移的是多个表空间,而且源数据库和目标数据库与上一个例子中的完全一致,因此这里选择了PULL_TABLESPACES过程。
由于环境和上一个例子完全一致,这里不需要进行数据库版本、数据块大小、以及字符集的检查,唯一需要检查的是,需要迁移表空间的一致性。
SQL> SELECT OWNER, TABLESPACE_NAME, SUM(BYTES)/1024/1024
2 FROM DBA_SEGMENTS
3 WHERE OWNER IN ('ZHIFU','DEMO_WH','JSJG','JS_DEV_OPER','DEMO_INFO','PMSADM','JSGOV','JS_DEV','JS_TEST')
4 GROUP BY OWNER, TABLESPACE_NAME;
OWNER TABLESPACE_NAME SUM(BYTES)/1024/1024
------------------------------ ------------------------------ --------------------
JSGOV JSGOV 2778.1875
JSJG JSJG 2230.6875
DEMO_INFO DEMO_WH_TBS 205.5
JS_DEV JSTBS 39215.3125
ZHIFU ZHIFU 1.625
JS_DEV_OPER JSTBS 7.625
DEMO_WH DEMO_WH_TBS 303.875
PMSADM DEMO_WH_TBS 488.4375
JS_TEST JIANGSU 10430.125
9 rows selected.
SQL> SELECT DISTINCT OWNER
2 FROM DBA_SEGMENTS
3 WHERE OWNER NOT IN
4 ('ZHIFU','DEMO_WH','JSJG','JS_DEV_OPER','DEMO_INFO','PMSADM','JSGOV','JS_DEV','JS_TEST')
5 AND TABLESPACE_NAME IN
6 (SELECT TABLESPACE_NAME
7 FROM DBA_SEGMENTS
8 WHERE OWNER IN
9 ('ZHIFU','DEMO_WH','JSJG','JS_DEV_OPER','DEMO_INFO','PMSADM','JSGOV','JS_DEV','JS_TEST'));
no rows selected
SQL> SELECT FILE_NAME
2 FROM DBA_DATA_FILES
3 WHERE TABLESPACE_NAME IN
4 (SELECT TABLESPACE_NAME
5 FROM DBA_SEGMENTS
6 WHERE OWNER IN
7 ('ZHIFU','DEMO_WH','JSJG','JS_DEV_OPER','DEMO_INFO','PMSADM','JSGOV','JS_DEV','JS_TEST'))
8 ORDER BY TABLESPACE_NAME, FILE_ID;
FILE_NAME
---------------------------------------------------------------------
/data/oracle/oradata/kaifa/demowarehouse01.dbf
/data/oracle/oradata/kaifa/jiangsu01.dbf
/data/oracle/oradata/kaifa/jsgov01.dbf
/data/oracle/oradata/kaifa/jsjg01.dbf
/data/oracle/oradata/kaifa/testjs01.dbf
/data/oracle/oradata/kaifa/testjs02.dbf
/data/oracle/oradata/kaifa/testjs03.dbf
/data/oracle/oradata/kaifa/testjs04.dbf
/data/oracle/oradata/kaifa/testjs05.dbf
/data/oracle/oradata/kaifa/testjs06.dbf
/data/oracle/oradata/kaifa/testjs07.dbf
/data/oracle/oradata/kaifa/testjs08.dbf
/data/oracle/oradata/kaifa/testjs09.dbf
/data/oracle/oradata/kaifa/testjs10.dbf
/data/oracle/oradata/kaifa/testjs11.dbf
/data/oracle/oradata/kaifa/testjs12.dbf
/data/oracle/oradata/kaifa/zhifu01.dbf
17 rows selected.
SQL> EXEC DBMS_TTS.TRANSPORT_SET_CHECK('JSGOV,JSJG,DEMO_WH_TBS,JSTBS,ZHIFU,JIANGSU')
PL/SQL procedure successfully completed.
SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected
检查目标数据库:
SQL> SELECT NAME
2 FROM V$TABLESPACE
3 WHERE NAME IN ('JSGOV','JSJG','DEMO_WH_TBS','JSTBS','ZHIFU','JIANGSU');
NAME
------------------------------
JIANGSU
JSTBS
SQL> SELECT DISTINCT OWNER FROM DBA_SEGMENTS
2 WHERE TABLESPACE_NAME IN ('JIANGSU', 'JSTBS');
OWNER
------------------------------
JIANGSU15
JIANGSU
SQL> ALTER TABLESPACE JSTBS RENAME TO JSTBS229;
Tablespace altered.
由于检查发现目标数据库和源数据库在表空间名称上出现了冲突,因此修改目标数据库的JSTBS表空间名称为JSTBS229,另外在源数据库中修改JIANGSU表空间为JS_TEST:
SQL> ALTER TABLESPACE JIANGSU RENAME TO JS_TEST;
Tablespace altered.
由于表空间出现重名的现象,除了在源数据库和目标数据库修改表空间之外,还需要特别注意一个地方,就是数据文件是否重名的问题:
SQL> SELECT FILE_NAME FROM DBA_DATA_FILES;
FILE_NAME
---------------------------------------------------------------------------------
/data/oradata/test08/system01.dbf
/data/oradata/test08/undotbs01.dbf
/data/oradata/test08/sysaux01.dbf
/data/oradata/test08/users01.dbf
/data/oradata/test08/shiyq01.dbf
/data/oradata/test08/js_temp01.dbf
/data/oradata/test08/js_temp02.dbf
/data/oradata/test08/js_trade01.dbf
/data/oradata/test08/js_trade02.dbf
/data/oradata/test08/js_trade03.dbf
/data/oradata/test08/js_ndmain01.dbf
/data/oradata/test08/ndmain01.dbf
/data/oradata/test08/ndmain02.dbf
/data/oradata/test08/ndmain03.dbf
/data/oradata/test08/ndmain04.dbf
/data/oradata/test08/ndmain05.dbf
/data/oradata/test08/gpotbs01.dbf
/data/oradata/test08/gpotbs02.dbf
/data/oradata/test08/gpotbs03.dbf
/data/oradata/test08/gpotbs04.dbf
/data/oradata/test08/gpotbs05.dbf
/data/oradata/test08/testzj01.dbf
/data/oradata/test08/testzj02.dbf
/data/oradata/test08/testzj03.dbf
/data/oradata/test08/testzj04.dbf
/data/oradata/test08/testzj05.dbf
/data/oradata/test08/testzj06.dbf
/data/oradata/test08/testzj07.dbf
/data/oradata/test08/testzj08.dbf
/data/oradata/test08/testzj09.dbf
/data/oradata/test08/testzj10.dbf
/data/oradata/test08/testzj11.dbf
/data/oradata/test08/oldjiangsu01.dbf
/data/oradata/test08/oldjiangsu02.dbf
/data/oradata/test08/jiesuan01.dbf
/data/oradata/test08/jiesuan02.dbf
/data/oradata/test08/jiesuan03.dbf
/data/oradata/test08/newjiangsu01.dbf
/data/oradata/test08/newjiangsu02.dbf
/data/oradata/test08/newjiangsu03.dbf
/data/oradata/test08/newjiangsu04.dbf
/data/oradata/test08/newjiangsu05.dbf
/data/oradata/test08/newjiangsu06.dbf
/data/oradata/test08/js_lyg.dbf
/data/oradata/test08/js_hc.dbf
/data/oradata/test08/test01.dbf
/data/oradata/test08/zj_lpd01.dbf
/data/oradata/test08/info_01.dbf
/data/oradata/test08/info_02.dbf
/data/oradata/test08/jshc_test01.dbf
/data/oradata/test08/TJSQ01.dbf
/data/oradata/test08/TJSQ02.dbf
/data/oradata/test08/TJSQ03.dbf
/data/oradata/test08/TJSQ04.dbf
/data/oradata/test08/sckc01.dbf
55 rows selected.
幸好数据文件名称没有出现重复,否则还需要对数据文件名称进行重命名。
由于进行过迁移表空间的操作,所有的目录都已经创建完成,数据库链也已经建立完成,下面需要创建目标数据库上的目标用户,首先获取源数据库用户授权的角色和权限:
SQL> SELECT 'GRANT ' || GRANTED_ROLE || ' TO ' || GRANTEE || ';'
2 FROM DBA_ROLE_PRIVS
3 WHERE GRANTEE IN ('ZHIFU','DEMO_WH','JSJG','JS_DEV_OPER','DEMO_INFO','PMSADM','JSGOV','JS_DEV','JS_TEST')
4 ORDER BY GRANTEE, GRANTED_ROLE;
'GRANT'||GRANTED_ROLE||'TO'||GRANTEE||';'
-----------------------------------------------------------------------
GRANT CONNECT TO DEMO_INFO;
GRANT RESOURCE TO DEMO_INFO;
GRANT CONNECT TO DEMO_WH;
GRANT RESOURCE TO DEMO_WH;
GRANT CONNECT TO JSGOV;
GRANT RESOURCE TO JSGOV;
GRANT CONNECT TO JSJG;
GRANT RESOURCE TO JSJG;
GRANT CONNECT TO JS_DEV;
GRANT RESOURCE TO JS_DEV;
GRANT CONNECT TO JS_DEV_OPER;
GRANT RESOURCE TO JS_DEV_OPER;
GRANT CONNECT TO JS_TEST;
GRANT RESOURCE TO JS_TEST;
GRANT CONNECT TO PMSADM;
GRANT RESOURCE TO PMSADM;
GRANT CONNECT TO ZHIFU;
GRANT RESOURCE TO ZHIFU;
18 rows selected.
SQL> SELECT 'GRANT ' || PRIVILEGE || ' TO ' || GRANTEE || ';'
2 FROM DBA_SYS_PRIVS
3 WHERE GRANTEE IN ('ZHIFU','DEMO_WH','JSJG','JS_DEV_OPER','DEMO_INFO','PMSADM','JSGOV','JS_DEV','JS_TEST')
4 AND PRIVILEGE NOT IN
5 (SELECT PRIVILEGE FROM DBA_SYS_PRIVS
6 WHERE GRANTEE IN ('CONNECT', 'RESOURCE'))
7 ORDER BY GRANTEE;
'GRANT'||PRIVILEGE||'TO'||GRANTEE||';'
---------------------------------------------------------------------------------
GRANT CREATE SYNONYM TO DEMO_INFO;
GRANT CREATE VIEW TO DEMO_INFO;
GRANT CREATE DATABASE LINK TO JSGOV;
GRANT CREATE MATERIALIZED VIEW TO JSGOV;
GRANT CREATE SYNONYM TO JSGOV;
GRANT CREATE VIEW TO JSGOV;
GRANT CREATE DATABASE LINK TO JSJG;
GRANT CREATE MATERIALIZED VIEW TO JSJG;
GRANT CREATE SYNONYM TO JSJG;
GRANT CREATE VIEW TO JSJG;
GRANT CREATE DATABASE LINK TO JS_DEV;
GRANT CREATE SYNONYM TO JS_DEV;
GRANT CREATE VIEW TO JS_DEV;
GRANT CREATE DATABASE LINK TO JS_DEV_OPER;
GRANT CREATE SYNONYM TO JS_DEV_OPER;
GRANT CREATE VIEW TO JS_DEV_OPER;
GRANT ALTER SESSION TO JS_TEST;
GRANT CREATE DATABASE LINK TO JS_TEST;
GRANT CREATE MATERIALIZED VIEW TO JS_TEST;
GRANT CREATE SYNONYM TO JS_TEST;
GRANT CREATE VIEW TO JS_TEST;
GRANT CREATE VIEW TO PMSADM;
GRANT CREATE DATABASE LINK TO ZHIFU;
GRANT CREATE SYNONYM TO ZHIFU;
GRANT CREATE VIEW TO ZHIFU;
25 rows selected.
利用上面的授权,就可以在目标数据库建立用户,并授权,篇幅所限,这个过程就省略了。
下面就可以执行PULL_TABLESPACES过程了,需要注意,这个过程的输入参数包括了索引组织表类型和记录,因此需要通过建立一个PL/SQL匿名块来完成调用,注意输入参数变量的声明需要用DBMS_STREAMS_TABLESPACE_ADM包中的类型进行声明,否则调用会报错:
SQL> DECLARE
2 V_JOB_NAME VARCHAR2(30) := 'MY_IMP_TABLESPACE';
3 V_TABLESPACE_NAME DBMS_STREAMS_TABLESPACE_ADM.TABLESPACE_SET;
4 V_DIRECTORY_NAME DBMS_STREAMS_TABLESPACE_ADM.DIRECTORY_OBJECT_SET;
5 V_LOGFILE DBMS_STREAMS_TABLESPACE_ADM.FILE;
6 BEGIN
7 V_TABLESPACE_NAME(1) := 'JSGOV';
8 V_TABLESPACE_NAME(2) := 'JSJG';
9 V_TABLESPACE_NAME(3) := 'DEMO_WH_TBS';
10 V_TABLESPACE_NAME(4) := 'JSTBS';
11 V_TABLESPACE_NAME(5) := 'ZHIFU';
12 V_TABLESPACE_NAME(6) := 'JS_TEST';
13 V_DIRECTORY_NAME(1) := 'D_TRANS';
14 V_LOGFILE.DIRECTORY_OBJECT := 'DMP_DIR';
15 V_LOGFILE.FILE_NAME := 'imp_tablespaces.log';
16 DBMS_STREAMS_TABLESPACE_ADM.PULL_TABLESPACES(V_JOB_NAME, 'KAIFA', V_TABLESPACE_NAME, V_DIRECTORY_NAME, V_LOGFILE);
17 END;
18 /
DECLARE
*
ERROR at line 1:
ORA-06512: at "SYS.DBMS_STREAMS_TABLESPACE_ADM", line 2355
ORA-06512: at line 16
表空间迁移过程报错了,从返回错误信息上看不出任何有意义的东西,检查一下对应的LOGFILE日志:
[oracle@yans1 backup]$ more imp_tablespaces.log
Starting "SYS"."MY_IMP_TABLESPACE":
Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
Processing object type TRANSPORTABLE_EXPORT/TABLE
Processing object type TRANSPORTABLE_EXPORT/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type TRANSPORTABLE_EXPORT/INDEX
Processing object type TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINT
Processing object type TRANSPORTABLE_EXPORT/INDEX_STATISTICS
Processing object type TRANSPORTABLE_EXPORT/COMMENT
Processing object type TRANSPORTABLE_EXPORT/CONSTRAINT/REF_CONSTRAINT
Processing object type TRANSPORTABLE_EXPORT/TRIGGER
ORA-39082: Object type TRIGGER:"JS_TEST"."CAT_REGION_CM_TR" created with compilation warnings
ORA-39082: Object type TRIGGER:"JS_TEST"."CAT_REGION_CM_TR" created with compilation warnings
ORA-39082: Object type TRIGGER:"JS_TEST"."DRG_ORDHITCOMMTEM_ON_NEWHOS" created with compilation warnings
ORA-39082: Object type TRIGGER:"JS_TEST"."DRG_ORDHITCOMMTEM_ON_NEWHOS" created with compilation warnings
ORA-39082: Object type TRIGGER:"JS_TEST"."ORD_HOSPITAL_CATALOG_BEIAN" created with compilation warnings
ORA-39082: Object type TRIGGER:"JS_TEST"."TRG_PRODUCT_SERIAL" created with compilation warnings
ORA-39082: Object type TRIGGER:"JS_TEST"."TRG_PRODUCT_SERIAL" created with compilation warnings
Processing object type TRANSPORTABLE_EXPORT/INDEX/FUNCTIONAL_AND_BITMAP/INDEX
Processing object type TRANSPORTABLE_EXPORT/INDEX/STATISTICS/FUNCTIONAL_AND_BITMAP/INDEX_STATISTICS
Processing object type TRANSPORTABLE_EXPORT/TABLE_STATISTICS
Job "SYS"."MY_IMP_TABLESPACE" stopped due to fatal error at 16:02:35
显然,表空间已经加载完成,只是由于个别对象的问题导致了错误信息。在数据库中检查表空间信息:
SQL> SELECT NAME FROM V$TABLESPACE
2 WHERE NAME IN ('JSGOV', 'JSJG', 'DEMO_WH_TBS', 'JSTBS', 'ZHIFU', 'JS_TEST');
NAME
------------------------------
JS_TEST
ZHIFU
JSTBS
DEMO_WH_TBS
JSJG
JSGOV
6 rows selected.
SQL> SELECT OWNER, COUNT(*)
2 FROM DBA_OBJECTS
3 WHERE OWNER IN ('ZHIFU','DEMO_WH','JSJG','JS_DEV_OPER','DEMO_INFO','PMSADM','JSGOV','JS_DEV','JS_TEST')
4 GROUP BY OWNER;
OWNER COUNT(*)
------------------------------ ----------
ZHIFU 13
JS_DEV 1444
PMSADM 30
JSJG 225
DEMO_WH 347
JSGOV 68
JS_DEV_OPER 31
JS_TEST 1572
DEMO_INFO 602
9 rows selected.
SQL> SELECT TABLESPACE_NAME, STATUS
2 FROM DBA_TABLESPACES
3 WHERE TABLESPACE_NAME IN ('JSGOV', 'JSJG', 'DEMO_WH_TBS', 'JSTBS', 'ZHIFU', 'JS_TEST');
TABLESPACE_NAME STATUS
------------------------------ ---------
DEMO_WH_TBS READ ONLY
JSGOV READ ONLY
JSJG READ ONLY
JSTBS READ ONLY
JS_TEST READ ONLY
ZHIFU READ ONLY
6 rows selected.
虽然执行DBMS_STREAMS_TABLESPACE_ADM包的PULL_TABLESPACES过程报错了,但是迁移表空间的操作已经完成。剩下根据需要决定是否对导入过程中的错误进行额外的处理。
表空间迁移完成后,加载的表空间处于只读状态,可以根据具体的需要决定是否将其置为可写状态。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-605055/ ,如需转载,请注明出处,否则将追究法律责任。