oracle邏輯備份之--資料泵

tangguowuvv發表於2018-03-02
寫這一篇關於資料泵的部落格,我一直抱有一種感恩之情,因為資料泵作為一種邏輯匯出匯入手段,在剛開始接觸oracle的時候,軍哥給我了大量的指導,所以每次我用到它的時候,都會想起前輩們對我不遺餘力的指導。寫此篇部落格,我將重憶學習歷程,對所有幫助過我的前輩們表示真誠的謝意。
特性描述:
oracle資料泵包括expdp匯出和impdp匯入,它是oracle 10g提供的一個新功能,是對舊的匯出(exp)和匯入(imp)工具的增強,但是它的特性還遠遠不止這些,我列出幾點:
1、對記錄的過濾更為細緻,包括include--正規則,exclude--反規則,query,sample引數來對記錄進行過濾;
2、parallel和filesize引數的結合使用,使得資料泵具有強大的並行處理能力;
3、支援修改schema的屬主,表空間和臨時表空間的屬主;
4、支援暫停和重啟匯入匯出任務。
下面開始正式進入expdp和impdp的學習:(我的測試系統版本是centos6.6)
一、建立directory
SQL> create directory dmp as '/opt/dmp'; 

註釋:directory目錄是oracle 10g提供的一個新功能,它是系統目錄和實際路徑的一個對應,比如在這裡,我建立的目錄名為dmp,它與/opt/dmp這個物理路徑對應,匯出資料的時候,我將資料匯出到dmp目錄,實際上匯出檔案儲存在/opt/dmp。
二、賦予匯出使用者read,write on directory的許可權,同時賦予匯出使用者expdp和impdp許可權
SQL>grant read,write on directory dmp to ceshi;
SQL> grant datapump_exp_full_database,datapump_imp_full_database to ceshi;
註釋:關於匯出使用者,在這裡使用者名稱為ceshi,使用ceshi這個使用者,只要賦予其許可權,它可以匯出匯入任何schema,tablespace,table等。如果使用特權使用者sys匯出,那麼必須使用sys匯入。
三、expdp匯出
(1)匯出schema
[oracle@oracledb ~]$ expdp ceshi/*** directory=dmp dumpfile=ceshi0224.dmp logfile=ceshi0224.log schemas=ceshi
註釋:可以看出,expdp和impdp命令都是系統命令,是在作業系統級別下操作的。expdp 使用者名稱/密碼 directory=系統目錄 dumpfile=匯出檔名字.dmp logfile=匯出日誌名.log shemas=匯出的schema。在這裡,使用者名稱/密碼 只要具有expdp許可權且對指定目錄具有讀寫許可權的使用者都可以,directory=系統目錄 這個是需要將資料匯出的位置,它對應了一個實際的物理路徑,dumpfile 是匯出的資料檔案,字尾為.dmp,logfile 是匯出日誌,字尾為.log,schemas 匯出schema使用者下的所有物件,如果不指定schemas,預設為執行匯出操作使用者的schema。在匯出完畢的時候,有這樣一段JOB "CESHI"."SYS_EXPORT_SCHEMA_01" successfully completed at 01:21:41,其中SYS_EXPORT_SCHEMA_01"是本次expdp的任務名(任務名相關請看下面的job_name和attach引數)。
結果如下:

(2)匯出tables,我將會以匯出表為例,列出expdp一些引數
<1>tables引數
[oracle@oracledb ~]$ expdp ceshi/*** directory=dmp dumpfile=ceshi0224.dmp logfile=ceshi0224.log tables=ceshi.GER_DIAGNOSIS,ceshi.OP_DRGS_ONLY
註釋:tables可以指定匯出哪一個chemas下的表
結果如圖:

<2>query和sample引數
[oracle@oracledb ~]$ expdp ceshi/*** directory=dmp dumpfile=ge.dmp logfile=ge.log  tables=ceshi.GER_DIAGNOSIS,ceshi.GER_OPERATION query=ceshi.GER_DIAGNOSIS:\"where code=\'A16.211\'\" sample=ceshi.GER_OPERATION:50
註釋:這個匯出的是ceshi.GER_DIAGNOSIS滿足 code='A16.211'ceshi.GER_OPERATION總記錄的百分之50,其中query=A:"where",表示對A表進行過濾,雙引號(")和單引號(')前都要加轉義符(\),sample=B:50,表示取B表50%的記錄行。如果沒有指定tables引數,那麼預設匯出該匯出使用者下的所有物件,只是給query和sample的物件做了過濾。
結果如圖:

<3>include和exclude引數
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ge.dmp logfile=ge.log include=table:\"in\(\'ceshi.GER_DIAGNOSIS\',\'ceshi.GER_OPERATION\'\)\"
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ge.dmp logfile=ge.log exclude=table:\"in\(\'ceshi.GER_DIAGNOSIS\',\'ceshi.GER_OPERATION\'\)\"
註釋:include(正規則)和exclude(反規則)可以對錶,索引和約束等物件進行過濾,這裡表示只匯出GER_DIAGNOSIS和GER_OPERATION這兩張表,當然,exclude=table:A,表示不匯出A表。
結果如下:(只貼出include的結果)

<4>parfile引數
[oracle@oracledb tmp]$ expdp ceshi/*** parfile=/tmp/p.txt
註釋:parfile引數的使用,可以直接呼叫已經寫好的命令列文字,而不用在介面上寫長串的命令,因為介面所能容納的字元數是有限的,同時由於不同的作業系統對特殊字元的轉義,必須在命令列加上跳脫字元,透過上面就可以看出來,對字元的轉義實在是比較麻煩,但是如果寫到文字中直接呼叫,就不用擔心不同的平臺字元轉義問題。
命令列文字如下:
[oracle@oracledb tmp]$ cat p.txt 
directory=dmp
dumpfile=ge.dmp
logfile=ge.log
include=table:"in('GER_DIAGNOSIS','GER_OPERATION')"
匯出結果如圖:

<5>進入互動模式
當正在expdp的時候,可以按ctrl+c
進入互動模式,對ctrl+c後還在執行的任務,可以export>kill_job,中斷正在執行的任務,可以export>stop_job,停止當前正在執行的任務,export>start_job,啟動停止的任務,export>status檢視當前任務的詳細狀態資訊。
如圖:

<6>add_file和continue_client引數
Export> add_file=ge02.dmp
Export> continue_client
註釋:進入互動模式之後,可以用add_file增加新的dmp檔案,在這裡還可以對dmp檔名指定命名引數,比如U%,這樣如果我指定ge03.dmp,ge04.dmp,expdp命令會根據需要,自動附加序號對檔名進行填充。新增完新的dmp檔案之後,可以輸入continue_client退出互動介面,進入匯出介面。
<7>grants,indexes,constraints,triggers引數
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ger.dmp logfile=ger.log tables=ceshi.GER_DIAGNOSIS,ceshi.GER_OPERATION grants=n
註釋:grants指定是否匯出物件的授權資訊,授權資訊指的是透過grant命令授予的物件訪問,操作許可權,預設為Y,也就是預設匯出;indexes指定是否匯出表的索引,預設為Y;constraints指定是否匯出表的約束,預設為Y;triggers是否匯出與表相關的觸發器,預設為Y。
<8>filesize和parallel引數
[oracle@oracledb dmp]$ expdp ceshi/*** parfile=/tmp/p.txt filesize=300m parallel=2
註釋:這兩個引數的結合使用,使得expdp的效率更高,filesize指定每個dmp檔案的大小,最大不能超過1G,parallel指定匯出的並行度,相當於多個程式同時執行expdp這個任務,速度當然更快,效率也當然更高,建議parallel引數的設定小於或者等於生成的dmp檔案個數。
結果如圖:(由於匯出單個表太小,因此這裡匯出了整個schema)

<9>network_link和nologfile引數
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=link.dmp nologfile=y network_link=to_qj tables=qj.t1,qj.t2
註釋:expdp是一個服務端命令,也就是說匯出的資料會存在伺服器端。但是可以透過network_link引數將遠端資料庫資料匯出到本地,在匯出之前,需要建立一個dblink連線到遠端資料庫,expdp ceshi/ceshi directory=dmp dumpfile=link.dmp 這幾個部分不變,執行匯出的使用者要求為本地使用者,nologfile=y的意思是不生成匯出日誌,預設會生成匯出日誌,tables表明如果想指定具體的表,需要在表的前面加上遠端資料庫schema名。
dblink的建立指令碼如下:
create public database link to_qj connect to qj identified by qj
using '(DESCRIPTION =
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.47)(PORT = 1521))
   )
   (CONNECT_DATA =
     (SERVER = DEDICATED)
     (SERVICE_NAME = ORCL.168.0.111))
)';
匯出結果如圖:

<10>job_name和attach引數
透過(1)匯出schemas的例子我們可以看到,對於每次的expdp,如果不指定任務名,那麼系統會自動生成一個任務名,可以透過job_name引數來顯式指定一個任務名。
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=link.dmp nologfile=y network_link=to_qj tables=qj.t1,qj.t2,qj.feedback job_name=expdp_qj
結果如圖:

對於異常退出,可以透過attach=任務名來重新執行未完成的任務。
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=link.dmp nologfile=y network_link=to_qj job_name=expdp_qj
在執行的過成功ctrl+c進入互動模式,然後exit_client退出互動模式,可以透過如下sql來檢視異常退出的expdp任務:
select job_name,operation,job_mode,state from user_datapump_jobs;

可以看到,job_name為expdp_qj的任務異常,如果想再次進入匯入介面,則使用attach=任務名,來重新連線到未完成的任務
[oracle@oracledb dmp]$ expdp ceshi/*** attach=expdp_qj 

可以看到再次進入了互動模式,然後在互動模式輸入contiune_client 就可以接著匯出資料了
Export> contiune_client 
(3)匯出表空間
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=tbs.dmp nologfile=y tablespaces=ceshi
註釋:tablespaces引數可以指定匯出固定表空間,對於schemas,tables,tablespaces,如果匯出多個,中間以逗號(,)隔開。
(4)匯出整個庫
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=full.dmp nologfile=y full=y
註釋:full引數可以指定對於整個庫的匯出,full=y,表示匯出整個資料庫,它將會匯出這個資料庫下的所有物件。
(5)只匯出物件的定義,而不匯出具體的記錄
[oracle@oracledb dmp]$ expdp ceshi/*** directory=dmp dumpfile=ceshi0224.dmp logfile=ceshi0224.log tables=ceshi.GER_DIAGNOSIS,ceshi.OP_DRGS_ONLY content=metadata_only
註釋:指定content=metadata_only,表示只匯出表的定義,而不匯出表的資料。
四、impdp匯入
(1)預設匯入(適合源庫和目標庫表空間和使用者建立方式一樣的情況,比如,建立了一個測試庫,結構和生產庫類似,需要定期將生產庫資料備份到測試庫)
[oracle@oracledb dmp]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp 
註釋:ceshi.dmp這個檔案是從其他庫匯出來的(比如從生產庫匯出的),匯出了ceshi這個schema,它所在的表空間名為ceshi(我只是為了方便,將使用者名稱和表空間名起成一樣的了,他們之間命名沒有任何關係)。拿到從其他庫匯出來的ceshi.dmp這個二進位制檔案,到需匯入的庫進行操作,impdp imp1/imp1 directory=dmp dumpfile=ceshi.dmp的意思是以imp1這個使用者(具有impdp許可權)將目錄dmp中名為ceshi.dmp的檔案匯入進去,沒有其他引數;那就意味著將資料匯入到ceshi這個使用者,當前庫中有沒有ceshi這個使用者都無所謂,如果有的話直接匯入ceshi使用者,如果沒有ceshi使用者,oracle會自動建立一個名為ceshi的使用者(不過此使用者所在表空間為預設表空間,這一點不太好,使用者所在表空間人為控制最好),匯入的表空間名必須為ceshi,所以當前庫必須已經建立了名為ceshi的表空間,否則預設匯入會報錯。綜上,如果不指定其他引數,那麼資料將會匯入到和源資料相同的使用者和表空間。我對於此種方式還是比較詬病的,一個是目標庫和源庫使用者名稱和表空間名很可能不同,我不能每次都要建立一個同名表空間;二:如果我當前庫沒有這個使用者,系統自動建立的使用者所在表空間很多時候不是我想要的,當然,如果我提前建立使用者就可以避免這個問題了。
(2)使用remap_schema和remap_tablespace引數(這兩個引數也是資料泵中相當令人欣喜的地方)
[oracle@oracledb ~]$ expdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log remap_schema=ceshi:user01 remap_tablespace=ceshi:users
註釋:remap_schema引數可以該變資料的屬主,這裡將ceshi變為了user01,remap_tablespace引數可以改變資料的預設表空間,這裡將預設表空間由ceshi改為了users。這樣一來,就可以完全對資料的儲存位置進行控制,讓整個資料的管理更為集中,更為科學化。我個人習慣於使用這種方式匯入資料。
結果如圖:


(3)content引數
[oracle@oracledb ~]$ expdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log content=metadata_only remap_schema=ceshi:user01 remap_tablespace=ceshi:users
註釋:content引數,該引數有3個屬性值:all(匯入物件定義和資料,該引數的預設值就是all),data_only(只匯入資料),metadata_only(只匯入物件定義)。
(4)table_exists_action引數
[oracle@oracledb ~]$ expdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log table_exists_action=replace remap_schema=ceshi:user01 remap_tablespace=ceshi:users
註釋:table_exists_action引數,該引數有4個屬性值:skip(跳過該表,繼續下一個物件的處理,這也是table_exists_action引數的預設值,不過需要注意,如果你同時指定了content引數為data_only的話,skip引數值無效,預設為append),append(向現有的表中新增資料),truncate(truncate當前表,然後再新增記錄,使用這個引數需要謹慎,除非確認當前表中資料確實無用,或者與要匯入的資料有重複,不然有可能造成資料丟失), replace(刪除並重建表物件,然後再向其中新增資料,不過需要注意,如果同時指定了content引數值為data_only的話,replace引數值也無效)。
(5)以下引數和expdp一樣,就不再貼圖了
指定schemas引數,表明匯入哪些schema,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log schemas=ceshi remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定tables引數,表明匯入哪幾張表,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log tables=ceshi.OP_DRGS_ONLY,ceshi.GER_DIAGNOSIS, remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定tablespaces引數,表明匯入哪些表空間,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log tablespaces=ceshi remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定query引數,表明匯入條件,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log  tables=ceshi.GER_DIAGNOSIS,ceshi.GER_OPERATION query=ceshi.GER_DIAGNOSIS:\"where code=\'A16.211\'\" remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定parfile引數,呼叫文字命令,例如:
[oracle@oracledb ~]$ impdp imp1/***  parfile=/tmp/p.txt
ctrl+c進入互動介面,可以import>kill_job,中斷正在執行的任務,可以import>stop_job,停止當前正在執行的任務,import>start_job,啟動停止的任務,import>status檢視當前任務的詳細狀態資訊。
continue_client引數,可以繼續進入匯入介面。
指定parallel引數,進行並行匯入,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp logfile=ceshi.log parallel=2 remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定network_link引數,將遠端使用者中的資料匯入本地使用者下,例如:
[oracle@oracledb ~]$ impdp imp1/*** network_link=to_qj remap_schema=qj:user01 remap_tablespace=qj01:users
指定nologfile引數,指定是否匯出匯入日誌,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp nologfile=y remap_schema=ceshi:user01 remap_tablespace=ceshi:users
指定job_name引數,為匯入任務命名,例如:
[oracle@oracledb ~]$ impdp imp1/*** directory=dmp dumpfile=ceshi.dmp nologfile=y job_name=impdp_qj remap_schema=ceshi:user01 remap_tablespace=ceshi:users
同樣對於異常退出,可以透過attach=任務名來,重新執行未完成的任務
五、與君共勉
資料泵在日常的資料庫管理中使用非常頻繁,可以非常方便的對資料進行遷移,雖然命令比較多,但這是一個非常好的地方,命令多,意味著靈活,對於各種要求的資料遷移遊刃有餘,因此還是需要勤加練習,在練習中將會遇到expdp和impdp各種問題,解決問題的過程本身就是一種學習,就是一種成長。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30485601/viewspace-2151455/,如需轉載,請註明出處,否則將追究法律責任。

相關文章