
遇到Oracle數(shù)據(jù)庫(kù)報(bào)錯(cuò)特別是一堆ORA-39002、ORA-29280這種跟文件目錄相關(guān)的錯(cuò)誤時(shí)DBA的第一反應(yīng)往往是同一個(gè)動(dòng)作去看create directory創(chuàng)建的目錄對(duì)象到底指向哪個(gè)路徑。這個(gè)目錄路徑聽(tīng)起來(lái)簡(jiǎn)單但實(shí)際工作中因?yàn)楦沐e(cuò)路徑導(dǎo)致數(shù)據(jù)泵失敗、外部表讀不到文件的案例我見(jiàn)過(guò)太多。Oracle里的directory對(duì)象本質(zhì)上只是一張映射記錄你執(zhí)行create directory時(shí)數(shù)據(jù)庫(kù)僅僅記下來(lái)“目錄對(duì)象名 - 操作系統(tǒng)路徑字符串”它不會(huì)幫你創(chuàng)建文件夾也不會(huì)校驗(yàn)這個(gè)路徑到底存不存在。想要搞清楚真實(shí)的目錄路徑全靠數(shù)據(jù)字典來(lái)查。這篇博文就把查詢create directory目錄路徑的各種方法、常見(jiàn)場(chǎng)景和排錯(cuò)思路完整梳理一遍內(nèi)容適合剛接觸Oracle的開(kāi)發(fā)者也適合要獨(dú)立搞定數(shù)據(jù)泵和外部表的初級(jí)DBA。1. 為什么目錄路徑這么值得查1.1 目錄對(duì)象是邏輯層和物理層之間的橋在Oracle里目錄對(duì)象是數(shù)據(jù)庫(kù)用來(lái)訪問(wèn)操作系統(tǒng)文件的一種中間層。它的創(chuàng)建語(yǔ)法非常簡(jiǎn)單CREATE DIRECTORY dump_dir AS /u01/app/oracle/dump;dump_dir是邏輯名稱/u01/app/oracle/dump是操作系統(tǒng)真實(shí)路徑。這么做最大的好處是應(yīng)用和數(shù)據(jù)庫(kù)腳本只需要記住一個(gè)邏輯對(duì)象名不需要把物理路徑寫(xiě)死在代碼里。但壞處也很明顯一旦物理路徑發(fā)生變化或者建對(duì)象的時(shí)候路徑本來(lái)就寫(xiě)錯(cuò)了數(shù)據(jù)庫(kù)不會(huì)給你任何提示。關(guān)鍵點(diǎn)在于數(shù)據(jù)庫(kù)進(jìn)程要讀寫(xiě)文件時(shí)不能直接使用裸的字符串路徑必須通過(guò)DIRECTORY對(duì)象來(lái)定位。所以EXPDP、IMPDP、外部表、BFILE凡是涉及外部文件的操作最終都會(huì)走到目錄對(duì)象的映射關(guān)系上來(lái)。查詢create directory的目錄路徑等于是在確認(rèn)數(shù)據(jù)庫(kù)認(rèn)為文件應(yīng)該放在哪里這是后續(xù)所有排障動(dòng)作的前提。注意CREATE DIRECTORY本身不會(huì)自動(dòng)創(chuàng)建操作系統(tǒng)目錄。這條命令只是登記了一個(gè)路徑字符串目錄不存在、權(quán)限不足Oracle并不關(guān)心直到真正讀寫(xiě)文件時(shí)報(bào)錯(cuò)你才會(huì)發(fā)現(xiàn)。1.2 數(shù)據(jù)泵、外部表和BFILE全都要靠它我遇到不少開(kāi)發(fā)伙伴把目錄路徑和服務(wù)端路徑搞混。EXPDP工具雖然可以在客戶端執(zhí)行但實(shí)際讀寫(xiě)dmp文件的位置是數(shù)據(jù)庫(kù)服務(wù)器上的路徑。假如你在客戶端機(jī)器上執(zhí)行expdp user/pass directorylocal_dump dumpfiletest.dmp這里的local_dump必須是在數(shù)據(jù)庫(kù)服務(wù)器上已經(jīng)創(chuàng)建好的目錄對(duì)象而不是客戶端隨便一個(gè)文件夾。如果兩邊沒(méi)對(duì)齊導(dǎo)出必然報(bào)錯(cuò)。更常見(jiàn)的場(chǎng)景是數(shù)據(jù)庫(kù)里已經(jīng)建了DATA_PUMP_DIR但服務(wù)器重啟后掛載點(diǎn)發(fā)生了變化或者運(yùn)維把目錄遷移到了新路徑。數(shù)據(jù)庫(kù)字典里的路徑?jīng)]變磁盤(pán)上卻早就沒(méi)有這個(gè)目錄了數(shù)據(jù)泵一跑就報(bào)ORA-39070找不到日志文件。這個(gè)時(shí)候第一步永遠(yuǎn)是查目錄路徑。外部表也是繞不開(kāi)目錄對(duì)象的。外部表在CREATE TABLE語(yǔ)句里指定DEFAULT DIRECTORY查詢數(shù)據(jù)時(shí)Oracle按目錄對(duì)象去定位文件。如果查詢結(jié)果里顯示的路徑和實(shí)際文件所在位置不一致外部表查詢會(huì)直接報(bào)ORA-29913或ORA-29280。BFILE同樣依賴目錄對(duì)象醫(yī)療影像、合同掃描件這類系統(tǒng)里尤其常見(jiàn)文件都放在共享目錄里路徑映射錯(cuò)了數(shù)據(jù)就是讀不出來(lái)。1.3 查目錄路徑是排查鏈路的第一站不是終點(diǎn)要特別提醒的是查到DBA_DIRECTORIES里的DIRECTORY_PATH只是拿到了數(shù)據(jù)庫(kù)認(rèn)為的路徑。真正能不能用還要看操作系統(tǒng)層面目錄是否存在、Oracle進(jìn)程用戶是否擁有權(quán)限。我在處理文件類錯(cuò)誤時(shí)基本按這個(gè)順序來(lái)查DBA_DIRECTORIES拿到數(shù)據(jù)庫(kù)內(nèi)記錄的路徑登錄數(shù)據(jù)庫(kù)服務(wù)器用ls -ld確認(rèn)目錄存在用stat或ls -ld查看目錄屬主和權(quán)限確認(rèn)Oracle進(jìn)程用戶對(duì)目錄有讀寫(xiě)權(quán)限做實(shí)際的寫(xiě)入或讀取測(cè)試。很多時(shí)候問(wèn)題不是出在第一步查詢而是出在第二、三步。但不管怎樣整個(gè)鏈路的第一步永遠(yuǎn)都是查create directory的目錄路徑。這一步做扎實(shí)了后面排查起來(lái)會(huì)順暢很多。2. 查詢目錄路徑的幾種常用方法2.1 首選DBA_DIRECTORIES一條SQL拿到全部映射最直接、最權(quán)威的查詢方法是查數(shù)據(jù)字典DBA_DIRECTORIESSELECT OWNER, DIRECTORY_NAME, DIRECTORY_PATH FROM DBA_DIRECTORIES;這個(gè)視圖會(huì)列出數(shù)據(jù)庫(kù)里所有目錄對(duì)象包括對(duì)象屬主、對(duì)象名稱和對(duì)應(yīng)的操作系統(tǒng)路徑。實(shí)際使用中如果你只想看某一個(gè)目錄SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME DATA_PUMP_DIR;我自己有個(gè)習(xí)慣查詢時(shí)永遠(yuǎn)把OWNER列帶出來(lái)。因?yàn)槟夸泴?duì)象的權(quán)限管理是按屬主展開(kāi)的不同用戶創(chuàng)建的目錄即使同名權(quán)限授予也可能完全不同。只查名稱和路徑容易在后續(xù)授權(quán)時(shí)踩坑。2.2 ALL_DIRECTORIES和USER_DIRECTORIES的區(qū)別不是所有賬號(hào)都能查詢DBA_DIRECTORIES。DBA_DIRECTORIES屬于管理視圖普通用戶直接查詢會(huì)報(bào)ORA-00942: table or view does not exist。這時(shí)候需要用ALL_DIRECTORIES或USER_DIRECTORIES。ALL_DIRECTORIES顯示當(dāng)前用戶有權(quán)限訪問(wèn)的目錄對(duì)象包括自己擁有的和已經(jīng)被授予訪問(wèn)權(quán)限的。USER_DIRECTORIES只顯示當(dāng)前用戶創(chuàng)建的目錄對(duì)象。大多數(shù)情況下業(yè)務(wù)賬號(hào)并不是DBA角色程序里如果用到了外部表通常只關(guān)心自己能用的目錄對(duì)象。這時(shí)候查詢可以寫(xiě)成SELECT DIRECTORY_NAME, DIRECTORY_PATH FROM ALL_DIRECTORIES WHERE OWNER USER;這個(gè)區(qū)別很重要但很多新手第一次執(zhí)行查詢報(bào)錯(cuò)后就以為系統(tǒng)里沒(méi)有建目錄其實(shí)只是視角不夠。先搞清楚當(dāng)前賬號(hào)的權(quán)限范圍再?zèng)Q定用哪個(gè)視圖能少走很多彎路。2.3 用DBMS_METADATA.GET_DDL還原目錄對(duì)象定義有些場(chǎng)景下我不光想看路徑還想還原當(dāng)時(shí)創(chuàng)建目錄對(duì)象的完整DDL尤其是要把目錄對(duì)象遷移到另一套環(huán)境的時(shí)候。用DBMS_METADATA.GET_DDL可以一次性拿到包含路徑的完整定義SELECT DBMS_METADATA.GET_DDL(DIRECTORY, DATA_PUMP_DIR) FROM DUAL;輸出結(jié)果大概是CREATE OR REPLACE DIRECTORY DATA_PUMP_DIR AS /u01/app/oracle/admin/ORCL/dpdump/這段DDL的價(jià)值在于它保留了對(duì)象名的大小寫(xiě)和引號(hào)狀態(tài)。如果你遇到一個(gè)目錄名看起來(lái)是小寫(xiě)但查詢時(shí)一直查不到八成是當(dāng)初創(chuàng)建時(shí)用了雙引號(hào)。用GET_DDL一看立刻明白問(wèn)題出在哪。2.4 在SQL*Plus里避免路徑被截?cái)嗄夸浡窂介L(zhǎng)的時(shí)候很常見(jiàn)ASM路徑、Windows盤(pán)符路徑、帶共享目錄的路徑隨便一拉就是七八十個(gè)字符。SQL*Plus默認(rèn)顯示寬度不夠時(shí)路徑會(huì)被截?cái)?。有人看到輸出只?u01/app/oracle/admin/ORC以為數(shù)據(jù)庫(kù)里的路徑不完整其實(shí)只是顯示問(wèn)題。查詢前先設(shè)置一下SET LINESIZE 300 SET PAGESIZE 100 COLUMN DIRECTORY_PATH FORMAT A100再執(zhí)行查詢路徑就能完整顯示出來(lái)。這個(gè)細(xì)節(jié)看起來(lái)小但現(xiàn)場(chǎng)排障時(shí)能省很多時(shí)間。用PL/SQL Developer、DBeaver、Navicat這些圖形工具時(shí)也要注意把列寬拉大否則一樣會(huì)看到截?cái)嘀怠?.5 在存儲(chǔ)過(guò)程或監(jiān)控腳本里動(dòng)態(tài)獲取路徑目錄路徑查詢不僅人工可以用還能集成到自動(dòng)化腳本里。比如寫(xiě)一個(gè)存儲(chǔ)過(guò)程定期檢查備份目錄是否存在并把結(jié)果記錄到日志表DECLARE v_path VARCHAR2(512); BEGIN SELECT DIRECTORY_PATH INTO v_path FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME BACKUP_DIR; -- 這里可以把v_path寫(xiě)入檢查日志表 DBMS_OUTPUT.PUT_LINE(v_path); END; /要注意PL/SQL的SELECT INTO必須保證只返回一行否則會(huì)報(bào)TOO_MANY_ROWS一行都查不到會(huì)報(bào)NO_DATA_FOUND。在監(jiān)控腳本里建議用游標(biāo)或異常處理包一層別讓環(huán)境里漏配目錄對(duì)象導(dǎo)致整個(gè)腳本崩潰。3. 實(shí)操場(chǎng)景拿到路徑之后怎么判斷和解決3.1 數(shù)據(jù)泵導(dǎo)出時(shí)報(bào)ORA-39002路徑怎么查怎么改場(chǎng)景執(zhí)行數(shù)據(jù)泵導(dǎo)出時(shí)提示ORA-39002: invalid operation。這個(gè)錯(cuò)誤本身只表示操作無(wú)效后面通常還會(huì)跟一串更具體的ORA-390xx錯(cuò)誤碼其中很大一部分的根源就是目錄路徑有問(wèn)題。排查時(shí)先把報(bào)錯(cuò)涉及的目錄對(duì)象名找出來(lái)再執(zhí)行SELECT DIRECTORY_NAME, DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME IN (DATA_PUMP_DIR, EXP_DIR);如果在結(jié)果里看到路徑是/u01/app/oracle/admin/ORCL/dpdump/而服務(wù)器上執(zhí)行l(wèi)s -ld /u01/app/oracle/admin/ORCL/dpdump提示No such file or directory那就說(shuō)明數(shù)據(jù)庫(kù)和操作系統(tǒng)兩邊沒(méi)對(duì)齊。解決辦法是重建目錄對(duì)象路徑。Oracle 11g之后可以優(yōu)先使用ALTER DIRECTORY DATA_PUMP_DIR AS /u01/app/oracle/dump;如果數(shù)據(jù)庫(kù)版本比較老或者ALTER執(zhí)行遇到兼容性問(wèn)題就用DROP再CREATE的方式DROP DIRECTORY DATA_PUMP_DIR; CREATE DIRECTORY DATA_PUMP_DIR AS /u01/app/oracle/dump; GRANT READ, WRITE ON DIRECTORY DATA_PUMP_DIR TO SCOTT;調(diào)整完再查一次DBA_DIRECTORIES確認(rèn)路徑已經(jīng)更新然后重新執(zhí)行expdp。這一步做完大部分?jǐn)?shù)據(jù)泵路徑問(wèn)題都能解決。注意ALTER DIRECTORY比較平滑對(duì)象已有的訪問(wèn)授權(quán)通常會(huì)保留DROP再CREATE則需要重新授權(quán)而且如果外部表正在引用該目錄操作瞬間會(huì)有對(duì)象失效風(fēng)險(xiǎn)。3.2 外部表讀不到文件先對(duì)照兩邊路徑外部表是很常見(jiàn)的目錄對(duì)象使用者。建外部表時(shí)一般是這樣CREATE TABLE ext_test ( id NUMBER, name VARCHAR2(100) ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY ext_dir ACCESS PARAMETERS (...) LOCATION (data.csv) );當(dāng)外部表查詢報(bào)ORA-29913或ORA-29280時(shí)我的檢查順序是用DBA_DIRECTORIES查出ext_dir對(duì)應(yīng)的路徑登錄服務(wù)器用ls確認(rèn)data.csv真實(shí)存在且文件名完全一致看Oracle進(jìn)程用戶是否可讀該文件檢查外部表定義里的文件名拼寫(xiě)包括大小寫(xiě)。這里有個(gè)很實(shí)際的經(jīng)驗(yàn)如果文件是從Windows機(jī)器上傳到Linux服務(wù)器的文件名大小寫(xiě)經(jīng)常對(duì)不上比如實(shí)際文件是Data.CSV外部表定義里寫(xiě)的卻是data.csv。Linux路徑和文件名都是大小寫(xiě)敏感的你查目錄路徑發(fā)現(xiàn)路徑?jīng)]錯(cuò)結(jié)果還是報(bào)錯(cuò)往往就卡在文件名大小寫(xiě)這里。3.3 目錄的物理路徑變了數(shù)據(jù)庫(kù)不會(huì)自動(dòng)知道操作系統(tǒng)上把目錄移動(dòng)了或者存儲(chǔ)換了掛載點(diǎn)數(shù)據(jù)庫(kù)里的目錄對(duì)象路徑不會(huì)跟著變。這個(gè)坑我在生產(chǎn)環(huán)境里踩過(guò)好幾次。比如原來(lái)目錄在/backup/exp后來(lái)運(yùn)維把整個(gè)數(shù)據(jù)卷遷移到了/data/exp并把/backup目錄刪掉了。數(shù)據(jù)庫(kù)里的目錄對(duì)象依然寫(xiě)著/backup/exp等于留下一個(gè)壞引用。解決方法就是更新路徑ALTER DIRECTORY exp_dir AS /data/exp;調(diào)整完一定要再查一次DBA_DIRECTORIES確認(rèn)路徑已經(jīng)更新。有些時(shí)候數(shù)據(jù)庫(kù)權(quán)限沒(méi)問(wèn)題、文件也存在但流程就是跑不通原因就是路徑指向了一個(gè)舊的、已經(jīng)被替換掉的掛載點(diǎn)。3.4 RAC和ASM環(huán)境下的路徑要所有節(jié)點(diǎn)可見(jiàn)單實(shí)例環(huán)境下目錄路徑只要本機(jī)存在就行。RAC環(huán)境不一樣每個(gè)節(jié)點(diǎn)上的數(shù)據(jù)庫(kù)實(shí)例都可能去讀寫(xiě)目錄對(duì)象指向的路徑。如果路徑是類似DATA/ORCL/DATAPUMP的ASM路徑數(shù)據(jù)庫(kù)會(huì)通過(guò)ASM實(shí)例統(tǒng)一管理如果是普通文件系統(tǒng)路徑就必須保證所有節(jié)點(diǎn)都能訪問(wèn)到通常建議放在共享文件系統(tǒng)上。查詢的時(shí)候你會(huì)在DBA_DIRECTORIES里看到這樣的路徑DATA/ORCL/DATAPUMP在RAC節(jié)點(diǎn)上ASM路徑和普通文件系統(tǒng)路徑語(yǔ)義不太一樣。出現(xiàn)路徑不可達(dá)時(shí)光在數(shù)據(jù)庫(kù)里查目錄對(duì)象是看不出來(lái)的還需要用asmcmd ls去看ASM目錄是否存在。這也是一個(gè)容易誤判的點(diǎn)DBA_DIRECTORIES顯示有路徑不代表數(shù)據(jù)庫(kù)真正能訪問(wèn)該路徑。它只是一張映射表不是資源可用性檢查表。4. 常見(jiàn)報(bào)錯(cuò)與排錯(cuò)速查4.1 查詢DBA_DIRECTORIES報(bào)ORA-00942普通用戶查詢DBA_DIRECTORIES沒(méi)權(quán)限時(shí)會(huì)報(bào)ORA-00942: table or view does not exist。常見(jiàn)解決方法是讓DBA授權(quán)GRANT SELECT ON DBA_DIRECTORIES TO SCOTT;不過(guò)我個(gè)人不太建議默認(rèn)把DBA_DIRECTORIES的查詢權(quán)限授給所有業(yè)務(wù)賬號(hào)。更合理的做法是讓業(yè)務(wù)賬號(hào)直接查ALL_DIRECTORIES只暴露自己可訪問(wèn)的目錄對(duì)象。如果確實(shí)需要全局視角再單獨(dú)給運(yùn)維賬號(hào)授權(quán)。4.2 查詢結(jié)果為空原因可能是大小寫(xiě)問(wèn)題目錄對(duì)象明明建了但查詢結(jié)果卻是零行。常見(jiàn)原因有兩個(gè)一是查詢時(shí)用了錯(cuò)誤的大小寫(xiě)二是建對(duì)象時(shí)用了雙引號(hào)把對(duì)象名存成了混合大小寫(xiě)或小寫(xiě)。遇到這種情況先不帶WHERE條件查全部SELECT OWNER, DIRECTORY_NAME, DIRECTORY_PATH FROM DBA_DIRECTORIES;如果目錄名是Backup_Dir這種混合大小寫(xiě)精確查詢時(shí)就必須按原樣寫(xiě)SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME Backup_Dir;如果沒(méi)有加引號(hào)Oracle默認(rèn)會(huì)把對(duì)象名存成大寫(xiě)所以查BACKUP_DIR才查得到。搞清楚這個(gè)規(guī)則很多“查不到”的問(wèn)題就迎刃而解。4.3 ORA-39070 找不到日志文件ORA-39070: cannot open the log file通常是日志文件路徑出了問(wèn)題。數(shù)據(jù)泵導(dǎo)出時(shí)不僅生成dmp文件還會(huì)生成日志文件日志默認(rèn)也寫(xiě)到DIRECTORY對(duì)象指定的路徑下。查一下路徑是否存在、是否可寫(xiě)如果目錄對(duì)象只授了讀權(quán)限導(dǎo)出會(huì)立刻失敗。這里必須強(qiáng)調(diào)兩層權(quán)限數(shù)據(jù)庫(kù)層的GRANT READ, WRITE ON DIRECTORY和操作系統(tǒng)層的文件權(quán)限。兩層都得有缺一個(gè)都不行。數(shù)據(jù)泵導(dǎo)入導(dǎo)出時(shí)常常需要同時(shí)讀寫(xiě)所以建議把WRITE權(quán)限也授予需要執(zhí)行導(dǎo)入導(dǎo)出的賬號(hào)。4.4 ORA-29280 文件不可訪問(wèn)ORA-29280常見(jiàn)于外部表或BFILE操作。它表示Oracle進(jìn)程無(wú)法打開(kāi)指定文件。除了路徑和權(quán)限問(wèn)題還可能是文件被其他進(jìn)程占用或者路徑里包含特殊字符導(dǎo)致解析異常。查詢路徑出來(lái)后用OS命令直接讀一下基本就能判斷是哪一層的問(wèn)題。4.5 常見(jiàn)問(wèn)題速查表報(bào)錯(cuò)或現(xiàn)象可能原因第一步排查動(dòng)作ORA-00942當(dāng)前用戶無(wú)權(quán)訪問(wèn)DBA_DIRECTORIES改用ALL_DIRECTORIES或向DBA申請(qǐng)授權(quán)查詢結(jié)果為空目錄名大小寫(xiě)、引號(hào)問(wèn)題先不帶WHERE條件查全部記錄ORA-39002目錄對(duì)象無(wú)效或路徑不可用查詢DBA_DIRECTORIES并核對(duì)OS路徑是否存在ORA-39070日志目錄不可寫(xiě)檢查目錄對(duì)象路徑和操作系統(tǒng)寫(xiě)權(quán)限ORA-29280文件不可訪問(wèn)檢查路徑、文件名大小寫(xiě)和權(quán)限外部表讀不到數(shù)據(jù)路徑或文件名不一致對(duì)照DBA_DIRECTORIES結(jié)果和OS的ls列表4.6 路徑顯示不完整路徑被截?cái)鄷r(shí)不要先懷疑數(shù)據(jù)字典里的數(shù)據(jù)有問(wèn)題先設(shè)置SQL*Plus的COLUMN和LINESIZE或者把圖形化工具里的列寬拉大。曾經(jīng)有同事把截?cái)嗪蟮穆窂街苯訌?fù)制去拼腳本結(jié)果路徑少了一段執(zhí)行時(shí)自然報(bào)錯(cuò)。所有從界面上復(fù)制的路徑都建議再執(zhí)行一次DBMS_METADATA.GET_DDL做二次確認(rèn)。5. 目錄路徑管理的幾條個(gè)人經(jīng)驗(yàn)5.1 系統(tǒng)默認(rèn)的DATA_PUMP_DIR別隨便改Oracle在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)通常會(huì)自動(dòng)建立一個(gè)DATA_PUMP_DIR指向$ORACLE_HOME/admin/實(shí)例名/dpdump/或$ORACLE_BASE/admin/實(shí)例名/dpdump/。測(cè)試庫(kù)里改一改沒(méi)什么生產(chǎn)環(huán)境里如果很多備份腳本都依賴這個(gè)默認(rèn)目錄貿(mào)然修改路徑會(huì)導(dǎo)致所有腳本一起失效。如果確實(shí)要改先查當(dāng)前路徑再全局搜索腳本里有沒(méi)有引用這個(gè)對(duì)象名最后用ALTER DIRECTORY更新。5.2 目錄路徑盡量規(guī)劃在獨(dú)立、持久化的掛載點(diǎn)生產(chǎn)環(huán)境里我不建議把目錄對(duì)象指向/tmp這種臨時(shí)目錄。很多系統(tǒng)會(huì)定期清理/tmp而且跨節(jié)點(diǎn)不一定可見(jiàn)。規(guī)劃時(shí)最好統(tǒng)一規(guī)則比如/u01/app/oracle/expdp、/backup/datapump。路徑統(tǒng)一了排查也方便腳本也容易復(fù)用。我自己習(xí)慣在路徑規(guī)則里帶上業(yè)務(wù)模塊名這樣DBA_DIRECTORIES一查出來(lái)基本能猜到是哪個(gè)業(yè)務(wù)在用什么目錄。5.3 做好路徑和權(quán)限的變更記錄這算是吃過(guò)虧的經(jīng)驗(yàn)。目錄路徑在運(yùn)維層面變化得頻率其實(shí)不低存儲(chǔ)擴(kuò)容、數(shù)據(jù)卷遷移、重新掛載都會(huì)導(dǎo)致物理路徑變化。數(shù)據(jù)庫(kù)端雖然不會(huì)感知但每次變更后最好順手執(zhí)行一次查詢把DBA_DIRECTORIES里的結(jié)果記錄下來(lái)和操作系統(tǒng)層對(duì)比一次。這樣后續(xù)再遇到文件類報(bào)錯(cuò)能很快判斷是不是路徑對(duì)不齊。5.4 最后說(shuō)一個(gè)很實(shí)用的小習(xí)慣我現(xiàn)在每次處理數(shù)據(jù)泵導(dǎo)出或外部表問(wèn)題第一句不是問(wèn)同事“你的SQL怎么寫(xiě)”而是讓他先執(zhí)行一條查詢SELECT OWNER, DIRECTORY_NAME, DIRECTORY_PATH FROM DBA_DIRECTORIES;然后讓他把結(jié)果發(fā)我。這一條SQL能省掉至少一半的無(wú)效溝通。因?yàn)榇蠖鄶?shù)問(wèn)題不是SQL語(yǔ)法而是路徑?jīng)]對(duì)上。數(shù)據(jù)泵報(bào)錯(cuò)、外部表報(bào)錯(cuò)、BFILE讀不到文件翻來(lái)覆去都是同一個(gè)核心Oracle里create directory的目錄路徑和操作系統(tǒng)真實(shí)路徑?jīng)]對(duì)齊。把這個(gè)查詢練熟了很多文件類問(wèn)題你都能在五分鐘內(nèi)找到方向。