ora-29289 错误根源是数据库层未授予用户对 directory 对象的 read/write 权限,而非 os 权限问题;需通过 dba_directories 和 dba_tab_privs 确认目录路径及权限,再由 sys/system 执行 grant read/write on directory。
ora-29289: directory access denied 怎么定位
这个错误不是数据库权限缺失,而是 oracle 拒绝访问某个 directory 对象——根本原因通常是:用户没被显式授予对该目录对象的 read 或 write 权限,哪怕该目录路径在 os 层可读写。
常见现象包括:UTL_FILE.FOPEN 失败、CREATE TABLE ... ORGANIZATION EXTERNAL 报错、EXPDP/IMPDP 无法写入或读取 dumpfile。
- 先确认报错时用的是哪个目录对象:查 SQL 中写的
'MY_DIR',或从错误堆栈里提取目录名 - 执行
SELECT * FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME = 'MY_DIR';,拿到DIRECTORY_PATH(比如/u01/dump) - 再查权限:
SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME = 'MY_DIR' AND PRIVILEGE IN ('READ','WRITE');—— 如果结果为空,就是没授权
GRANT READ/WRITE ON DIRECTORY 必须由谁执行
只有具备 GRANT ANY OBJECT PRIVILEGE 或者是该 DIRECTORY 的创建者(owner),才能授予权限。普通用户即使拥有 CREATE ANY DIRECTORY,也不能给他人授予权限。
实际操作中,几乎总是由 SYS 或 SYSTEM 执行:
GRANT READ, WRITE ON DIRECTORY MY_DIR TO app_user;- 如果只读需求(如外部表加载),只需
GRANT READ ON DIRECTORY MY_DIR TO app_user; - 注意:不能写成
GRANT READ ON MY_DIR TO ...—— 少了DIRECTORY关键字会报 ORA-00942 - 授完权后,用户无需重新连接,但若已打开的会话正在用 UTL_FILE 句柄,需重开
为什么改了 OS 权限还是报 ORA-29289
因为 Oracle 的 DIRECTORY 权限和操作系统文件权限是两层独立校验:OS 层允许 oracle 用户读写路径,不等于数据库层允许用户访问该 DIRECTORY 对象。
典型误操作:
- 只执行了
chown oracle:oinstall /u01/dump && chmod 755 /u01/dump,但忘了GRANT - 误以为
CONNECT或RESOURCE角色包含目录访问权 —— 它们完全不相关 - 把目录路径写错,比如
DIRECTORY_PATH是/u01/dump/(结尾有斜杠),而代码里传的是'/u01/dump'(无斜杠),虽然 OS 层等价,但 Oracle 不做路径归一化,DIRECTORY对象仍指向原路径
EXPDP/IMPDP 报 ORA-29289 时的特殊注意点
数据泵走的是服务器端路径,且强制要求:执行用户必须同时拥有 READ 或 WRITE 权限,**且**该用户必须对 DIRECTORY_PATH 对应的 OS 路径有对应权限(oracle 用户能读/写)。
- 例如:用
app_user执行expdp app_user/password DIRECTORY=MY_DIR DUMPFILE=test.dmp,则app_user必须被GRANT WRITE ON DIRECTORY MY_DIR,且oracleOS 用户必须能往/u01/dump/写文件 - 别依赖
DATA_PUMP_DIR:它默认指向$ORACLE_HOME/rdbms/log,权限常受限;生产环境务必自建DIRECTORY并严格控制 - 如果用
expdp / AS SYSDBA,仍要确保SYS被授予对应目录的READ/WRITE—— 默认不自动拥有
目录对象的权限控制是纯数据库层行为,和 OS 用户身份解耦;但数据泵等工具会同时触发两层检查,漏掉任何一层都会卡在 ORA-29289。











