對於Oracle的數據導出和導入,我們之前一直使用exp、imp來處理, 但用imp在導入時經常會要求表空間一致,而博主今天恰恰就遇到了需要變更表空間和用戶的情況,這在我們平常的業務場景中也會遇到,那麼該如何處理呢?
我們採用Oralce的 “數據泵” Data Dump來處理。
測試環境:Windows Server 2008 R2、Oracle11g
目錄
1、數據泵(Data Dump)主要解決問題
①. 比imp/exp更加靈活,支持多種元數據過濾策略,多種導入、導出模式,如將A表空間B用戶數據導入C表空間D用戶下,則只需REMAP_SCHEMA即可
②. 表空間佔用和表空間變更問題,可使用REMAP_TABLESPACE來解決
③. 空表問題,Oracle11g新的表並且表中無數據也爲使用過則表的segment空間是不會分配的,這樣在使用exp導出時空表便不會被導出,解決這個問題要麼給空分配segment或直接使用expdp。
④. 效率問題。普通情況下expdp/impdp比exp/imp效率要高,高多少博主沒有測試,有興趣的不妨驗證下,@博主。
2、數據泵使用限制
使用expdp、impdp有條件限制
一是遠程使用時必須配置好Database Link,因爲expdp、impdp只能在服務端使用,不能再客戶端使用;
二是試用前要解決路徑配置問題。
3、創建測試數據庫
創建源用戶和表空間,爲了便於操作我們給新創建用戶授權的了dba權限,大家在本地使用時注意
/*第1步:創建臨時表空間 */
create temporary tablespace test_source_temp
tempfile 'D:\Oracle11g\oradata\test_source_temp.dbf'
size 10m
autoextend on
next 1m maxsize unlimited
extent management local;
/*第2步:創建數據表空間 */
create tablespace test_source
logging
datafile 'D:\Oracle11g\oradata\test_source.dbf'
size 10m
autoextend on
next 1m maxsize unlimited
extent management local;
/*第3步:創建用戶並指定表空間 */
create user test_source identified by a123456
default tablespace test_source
temporary tablespace test_source_temp;
/*第4步:給用戶授予權限 */
grant connect,resource,dba to test_source;
創建兩張測試表,一張基礎數據類型,一張含clob、blob、date等複雜數據類型
--表1
create table tab_1
(
tab1_field1 number,
tab1_field2 varchar2(20),
tab1_field3 varchar2(10)
)
--插入測試數據
insert into TAB_1 (tab1_field1, tab1_field2, tab1_field3) values (1, 'a12', 'a13');
insert into TAB_1 (tab1_field1, tab1_field2, tab1_field3) values (2, '張22', '李23');
--表2
create table TAB_2
(
tab2_field1 NUMBER,
tab2_field2 VARCHAR2(20),
tab2_field3 DATE,
tab2_field4 CLOB,
tab2_field5 BLOB
)
--插入測試數據
insert into TAB_2 (tab2_field1,tab2_field2,tab2_field3,tab2_field4,tab2_field5) values ('1','A12',SYSDATE,'測試1','C1');
insert into TAB_2 (tab2_field1,tab2_field2,tab2_field3,tab2_field4,tab2_field5) values ('1','測試22',SYSDATE,'測試2','C2');
insert into TAB_2 (tab2_field1,tab2_field2,tab2_field3,tab2_field4,tab2_field5) values ('1','嘿嘿32',SYSDATE,'測試3','C3');
創建目標用戶和表空間
/*第1步:創建臨時表空間 */
create temporary tablespace test_target_temp
tempfile 'D:\Oracle11g\oradata\test_target_temp.dbf'
size 10m
autoextend on
next 1m maxsize unlimited
extent management local;
/*第2步:創建數據表空間 */
create tablespace test_target
logging
datafile 'D:\Oracle11g\oradata\test_target.dbf'
size 10m
autoextend on
next 1m maxsize unlimited
extent management local;
/*第3步:創建用戶並指定表空間 */
create user test_target identified by a123456
default tablespace test_target
temporary tablespace test_target_temp;
/*第4步:給用戶授予權限 */
grant connect,resource,dba to test_target;
4、導出源數據庫
這裏需要注意:
EXP和IMP是客戶端工具程序,它們既可以在客戶端使用,也可以在服務端使用。
而EXPDP和IMPDP是服務端的工具程序,他們只能在ORACLE服務端使用,不能在客戶端使用。
IMP只適用於EXP導出的文件,不適用於EXPDP導出文件;IMPDP只適用於EXPDP導出的文件,而不適用於EXP導出文件。
我們這裏需要使用expdp導出,需在服務端執行。
①.創建邏輯目錄
--創建一個dump路徑的對象
create directory dump_dir1 AS 'D:\Oracle11g\admin\orcl\dpdump';
當然我們這裏也可以使用dump默認目錄,查詢默認目錄,然後執行創建
--查詢使用默認dump路徑
select * from dba_directories where directory_name='DATA_PUMP_DIR';
--創建一個dump路徑的對象
create directory dump_dir1 AS 'D:\Oracle11g\admin\orcl\dpdump';
--查詢已創建的dump路徑對象
select * from dba_directories where directory_name='DUMP_DIR1';
但正常情況下這個目錄只有dba 和system高級用戶可以使用,所以我們需要給用戶授權,這裏我們同時給源數據庫用戶和目標數據庫用戶均加上目錄授權。
--用戶地址讀寫授權
grant read,write on directory dump_dir1 to test_source;
grant read,write on directory dump_dir1 to test_target;
②.導出源數據庫
在數據庫服務器上,點擊Win+R彈出命令框,輸入“cmd”,進入命令操作框,輸入以下語句,導出數據文件dmp。
1)按用戶導
expdp test_source/a123456 directory=dump_dir1 dumpfile=test_source.dmp schemas=test_source;
2)並行進程parallel
expdp test_source/a123456 directory=dump_dir1 dumpfile=test_source.dmp parallel=40 job_name=test_source
3)按表名導
expdp test_source/a123456 directory=dump_dir1 dumpfile=test_source.dmp tables=tab_1,tab_2;
4)按查詢條件導
expdp test_source/a123456 directory=dump_dir1 dumpfile=test_source.dmp tables=tab_1 query='where deptno=20';
5)按表空間導
expdp test_source/a123456 directory=dump_dir1 dumpfile=test_source.dmp tablespaces=test_source;
6)導整個數據庫
expdp test_source/a123456 directory=dump_dir1 dumpfile=test_source.dmp full=y;
我採用按用戶導出測試,發現報以下錯誤
然後打開目錄“”發現該目錄爲只讀目錄,去掉只讀選項,確認,同時增加日誌文件指向
再次嘗試,成功!
5、導入目標數據庫
上面我們已經給目標數據庫用戶加上了目錄授權,可以通過下面語句進行導入:
1)導到指定用戶下
impdp test_target/a123456 directory=dump_dir1 dumpfile=test_source.dmp schemas=test_target;
2)改變表的owner
impdp test_target/a123456 directory=dump_dir1 dumpfile=test_source.dmp tables=test_target.tab_1,test_target.tab_2 remap_schema=test_target;
3)導入表空間
impdp test_target/a123456 directory=dump_dir1 dumpfile=test_source.dmp tablespaces=test_target;
4)導入數據庫
impdb test_target/a123456 directory=dump_dir1 dumpfile=test_source.dmp full=y;
5)追加數據
impdp test_target/a123456 directory=dump_dir1 dumpfile=test_source.dmp schemas=test_target table_exists_action
我們採用導入指定用戶下,同時改變他的owner和表空間
impdp test_target/a123456 directory=dump_dir1 dumpfile=test_source.dmp remap_schema=test_source:test_target
remap_tablespace=test_source:test_target
導入完成!
6、驗證導入後表空間
我們驗證下導入後的表所屬用戶和表空間是否有變化
所屬用戶和表空間已發生改變。
爲了確保blob、clob等字段所屬表空間已改變,我們刪除源數據庫用戶和表空間,測試目標數據庫是否正常
--刪除源數據庫用戶
drop user test_source;
--因爲所刪表空間非空,所以我們加上including contents進行表空間刪除
drop tablespace test_source including contents and datafiles;
然後我們查詢下帶有clob和blob字段的表數據是否正常
成功,完美!