在上一章介紹expdp/impdp時曾使用過DIRECTORY這個概念,下面再簡單說明下DIRECTORY的點點滴滴。
MOS上對DIRECTORY的解釋(266875.1):
(1)、基於服務端 vs 基於客戶端
DIRECTORY變量指出了expdp導出數據泵或impdp導入數據泵將dump文件、log文件以及SQL文件(僅適用於impdp)寫到什麼路徑。
因為導出數據泵和導入數據泵都是基於服務端的,不是基於客戶端的,因此輸出文件的路徑都是相對於服務端目錄的路徑。數據泵要求將目錄路徑作為一個目錄對象。一個目錄對象將文件系統的一個目錄路徑映射為一個名稱。
(2)、如何創建一個目錄對象?
為了創建目錄,必須具有DBA角色或者賦予了CREATE ANY DIRECTORY權限。
示例:
Window平台
CONNECT system/manager
CREATE OR REPLACE DIRECTORY my_dir as 'D:\DataPump';
CREATE OR REPLACE DIRECTORY my_logdir as 'E:\logs';
GRANT read, write ON DIRECTORY my_dir TO scott;
GRANT read, write ON DIRECTORY my_logdir TO scott;
Unix平台
CONNECT system/manager
GRANT CREATE ANY DIRECTORY TO scott;
CONNECT scott/tiger
CREATE OR REPLACE DIRECTORY my_dir as '/usr/DataPump';
CREATE OR REPLACE DIRECTORY my_logdir as '/usr/logs';
如果普通用戶被賦予了CREATE ANY DIRECTORY權限,那麼用戶就自動具備目錄的READ和WRITE權限。
注意:CREATE DIRECTORY語句不會創建磁盤的真實目錄,如果目錄是無效的,數據泵作業會報錯:
ORA-39002: invalid operation
ORA-39070: Unable to open the log file.
ORA-29283: invalid file operation
ORA-06512: at "SYS.UTL_FILE", line 475
ORA-29283: invalid file operation
(3)、如何查詢可用的目錄?
可以使用如下SQL查詢具有READ和WRITE權限的目錄:
SET lines 80
COL grantee FORMAT a20
COL privilege FORMAT a10
SELECT directory_name, grantee, privilege
FROM user_tab_privs t, all_directories d
WHERE t.table_name(+)=d.directory_name
ORDER BY 1,2,3;
DIRECTORY_NAME GRANTEE PRIVILEGE
------------------------------ -------------------- ----------
DATA_PUMP_DIR EXP_FULL_DATABASE READ
DATA_PUMP_DIR EXP_FULL_DATABASE WRITE
DATA_PUMP_DIR IMP_FULL_DATABASE READ
DATA_PUMP_DIR IMP_FULL_DATABASE WRITE
MY_DIR SCOTT READ
MY_DIR SCOTT WRITE
MY_DIR SYSTEM READ
MY_DIR SYSTEM WRITE
MY_LOGDIR SCOTT READ
MY_LOGDIR SCOTT WRITE
MY_LOGDIR SYSTEM READ
MY_LOGDIR SYSTEM WRITE
...
(4)、需要的操作系統權限。
對目錄對象的READ或WRITE權限僅僅表示Oracle將會替你讀或寫這個文件。你並沒有訪問Oracle以外文件的權限,除非你具備合適的操作系統權限。
(5)、數據泵如何決定文件的路徑
5.1 如果目錄對象是文件標示符的一部分,那麼目錄對象指定的路徑就需要使用。在目錄MY_DIR創建dump文件的示例:
> expdp scott/tiger DUMPFILE=my_dir:expdp_s.dmp NOLOGFILE=Y
5.2 如果目錄對象不代表一個文件,那麼就需要使用DIRECTORY變量命名的目錄對象。目錄MY_DIR中創建dump文件,目錄MY_DIR_LOG中創建日志文件的示例:
> expdp scott/tiger DIRECTORY=my_dir DUMPFILE=expdp_s.dmp \
LOGFILE=my_logdir:expdp_s.log
5.3 如果沒有明確目錄對象,也沒有以DIRECTORY變量命名的目錄對象,那麼環境變量DATA_PUMP_DIR將會使用。環境變量是在在運行導出和導入數據泵應用的客戶端系統中使用操作系統命令定義的,分配給基於客戶端環境變量的取值必須和基於服務端的目錄對象一致,且必須首先在服務器端建立。
目錄MY_DIR中創建dump文件和MY_DIR_LOG中創建日志文件的示例:
在使用expdp的客戶端機器上,設定環境變量:
-- On windows, place all expdp parameters on one single line:
C:\> set DATA_PUMP_DIR=MY_DIR
C:\> expdp scott/tiger@my_db_alias DUMPFILE=expdp_s.dmp
LOGFILE=my_logdir:expdp_s.log
注意環境變量DATA_DUMP_DIR對應的目錄名稱是大小寫敏感的。設定錯誤的DATA_PUMP_DIR環境變量會報錯,例如:DATA_PUMP_DIR=My_Dir:
ORA-39002: invalid operation
ORA-39070: Unable to open the log file.
ORA-39087: directory name My_Dir is invalid
5.4 如果之前三種情況都沒有創建目錄對象,作為一個具有權限的用戶(例如具有EXP_FULL_DATABASE或IMP_FULL_DATABASE角色),那麼數據泵試圖使用默認的基於服務器端的目錄對象,DATA_PUMP_DIR。理解數據泵不會創建DATA_PUMP_DIR目錄對象是非常重要的。僅當授權用戶未使用任何之前提到的機制創建的目錄對象時,才會嘗試使用DATA_PUMP_DIR。這個默認的目錄對象必須首先由DBA創建。不要將這個和同名的基於客戶端的環境變量相混淆。
首先,清空DATA_PUMP_DIR環境變量:
C:\> set DATA_PUMP_DIR=
創建DATA_PUMP_DIR的目錄:
CONNECT SYSTEM/MANAGER
CREATE OR REPLACE DIRECTORY data_pump_dir AS 'D:\DataPump';
GRANT read, write ON DIRECTORY data_pump_dir TO scott;
-- On windows, place all expdp parameters on one single line:
C:\> expdp system/manager@my_db_alias DUMPFILE=expdp_s.dmp
LOGFILE=expdp_s.log SCHEMAS=scott
如果SCOTT用戶不是授權用戶,不能使用默認的DATA_PUMP_DIR。
ORA-39002: invalid operation
ORA-39070: Unable to open the log file.
ORA-39145: directory object parameter must be specified and non-null
用戶SCOTT的解決方法:如上面5.3,SCOTT可以設置環境變量DATA_PUMP_DIR為MY_DIR:
-- On windows, place all expdp parameters on one single line:
C:\> set DATA_PUMP_DIR=MY_DIR
C:\> expdp scott/tiger@my_db_alias DUMPFILE=expdp_s.dmp
LOGFILE=expdp_s.log SCHEMAS=scott
或者這種特定場景下,用戶SCOTT也可以有目錄DATA_PUMP_DIR的讀和寫權限:
-- On windows, place all expdp parameters on one single line:
C:\> set DATA_PUMP_DIR=DATA_PUMP_DIR
C:\> expdp scott/tiger@my_db_alias DUMPFILE=expdp_s.dmp
LOGFILE=expdp_s.log SCHEMAS=scott
實驗:
創建目錄:CREATE DIRECTORY UTL_FILE_DIR AS '/oracle/backup';
向用目錄對象標識的文件寫內容:
SQL> declare