ORA-31631错误表明用户缺少EXP_FULL_DATABASE或DATAPUMP_EXP_FULL_DATABASE系统级权限,需以SYSDBA身份显式授予该角色(而非仅授DBA),并注意CDB/PDB容器切换及版本差异。

expdp报错ORA-31631: requires EXP_FULL_DATABASE privilege
执行 expdp 时出现这个错误,说明当前用户缺少执行全库或跨用户导出所必需的系统级权限。这不是目录权限问题,而是数据库角色授权缺失——哪怕目录、路径、表都存在,没这个角色照样卡住。
-
EXP_FULL_DATABASE是 Oracle 数据泵导出的硬性门槛,尤其当使用full=y、schemas=xxx,yyy(多用户)、或导出非自身拥有的对象时必须具备 - 普通应用用户默认只有自己 schema 下对象的访问权,
expdp不会自动降级为“只导自己”,它要么有权限,要么直接报错 - 注意:该权限必须由
SYS或具有DBA角色的用户授予,且不能通过角色间接继承(比如把DBA角色授给一个角色再授给用户,不生效)
授予EXP_FULL_DATABASE权限的正确操作顺序
权限必须在 SQL*Plus 或 SQL Developer 中以 DBA 身份执行,不是在 CMD 或 Bash 里运行 expdp 命令时加参数能绕过的。
- 先确认目标用户是否存在:
SELECT username FROM dba_users WHERE username = 'APP_USER'; - 用
SYS AS SYSDBA登录后执行:GRANT EXP_FULL_DATABASE TO APP_USER; - 如果还需导入,顺带加上:
GRANT IMP_FULL_DATABASE TO APP_USER; - 权限生效无需重启实例,但若用户已建立连接,建议重新登录一次再试
expdp
为什么GRANT DBA不行?或者“已经授过还是报错”?
常见误操作是以为 GRANT DBA TO user 就够了,但实际上 Oracle 12c 及以后版本(尤其是 PDB 环境)中,DBA 角色默认不包含 EXP_FULL_DATABASE —— 它被拆成独立权限项,必须显式授予。
- 检查是否真授予成功:
SELECT * FROM dba_role_privs WHERE grantee = 'APP_USER' AND granted_role IN ('EXP_FULL_DATABASE', 'IMP_FULL_DATABASE'); - 若在 CDB 环境下操作 PDB,必须先
ALTER SESSION SET CONTAINER=pdb_name;,再执行GRANT,否则权限只落在 CDB$ROOT - 某些加固环境会禁用
EXP_FULL_DATABASE,改用更细粒度的DATAPUMP_EXP_FULL_DATABASE(19c+),此时应授后者:GRANT DATAPUMP_EXP_FULL_DATABASE TO APP_USER;
不想给高危权限?替代方案有哪些
如果安全策略禁止授予 EXP_FULL_DATABASE,又确实要导出非本用户的对象,只能换思路,没有“低权限通吃”的办法。
- 让拥有权限的用户代为导出,例如用
SYSTEM用户执行:expdp system/pwd@pdb directory=DATA_PUMP_DIR schemas=APP_USER dumpfile=app_user.dmp - 应用用户只导自己 schema,就别写
schemas=xxx(除非 xxx ≠ 当前用户),直接省略该参数,用默认行为即可 - 若只是导出几张表,且已有表级 SELECT 权限,可用
tables=tab1,tab2+query="WHERE...",但仍需确保用户对这些表有SELECT,且未被虚拟私有数据库(VPD)策略拦截
权限配置本身不复杂,但容易卡在容器切换、角色拆分、或误以为“DBA 就等于全能”这几个点上。真正难的是判断——你到底需要导什么范围的数据,再决定该走授权路线,还是换人/换方式执行。


















