expdp SCHEMAS=user 不导出权限,因其设计目标是迁移对象及其依赖,而非安全策略;权限分散在DBA_SYS_PRIVS等视图中,默认不采集。

expdp 本身不导出用户权限定义(如 GRANT 语句),它只导出对象结构、数据和元数据(比如表、索引、约束、触发器等)。用户权限(尤其是系统权限、角色授权、对象级 GRANT)不会被包含在默认的 SCHEMAS=xxx 导出中,除非显式要求。
要拿到指定用户的全部权限定义,得绕开 expdp 的“对象导出”逻辑,改用 SQL 查询拼出可执行的授权语句。
为什么 expdp SCHEMAS=user 不导出权限?
因为 Data Pump 的设计目标是迁移「对象及其依赖」,不是迁移「安全策略」。权限属于数据库级元数据,分散在 DBA_SYS_PRIVS、DBA_ROLE_PRIVS、DBA_TAB_PRIVS 等视图中,expdp 默认不采集这些内容。
如何生成该用户的完整权限 SQL 脚本?
在数据库中以 DBA 或具有查询权限的用户(如 SYSTEM)身份执行以下查询,手动拼出 GRANT 语句:
- 系统权限:
SELECT 'GRANT ' || PRIVILEGE || ' TO ' || GRANTEE || DECODE(ADMIN_OPTION, 'YES', ' WITH ADMIN OPTION;') || ';' FROM DBA_SYS_PRIVS WHERE GRANTEE = 'YOUR_USER';
- 角色权限:
SELECT 'GRANT ' || GRANTED_ROLE || ' TO ' || GRANTEE || DECODE(ADMIN_OPTION, 'YES', ' WITH ADMIN OPTION;') || ';' FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'YOUR_USER';
- 对象权限(含所有者):
SELECT 'GRANT ' || PRIVILEGE || ' ON ' || OWNER || '.' || TABLE_NAME || ' TO ' || GRANTEE || DECODE(GRANTABLE, 'YES', ' WITH GRANT OPTION;') || ';' FROM DBA_TAB_PRIVS WHERE GRANTEE = 'YOUR_USER';
注意:YOUR_USER 需替换成大写用户名;若用户有大量对象权限,结果可能很长,建议用 SPOOL 输出到文件。
能否让 expdp 顺带导出权限?
不能直接导出为可执行 SQL,但可以导出权限相关的元数据(仅限于该用户拥有的对象上的 GRANT,且需满足两个条件):
- 必须使用
CONTENT=ALL或CONTENT=METADATA_ONLY(不能是DATA_ONLY) - 必须加上参数
INCLUDE=GRANT,例如:expdp system/password SCHEMAS=USER_A DIRECTORY=dpump_dir DUMPFILE=user_a_grants.dmp CONTENT=METADATA_ONLY INCLUDE=GRANT
- 这个
INCLUDE=GRANT只捕获「该用户作为被授权者(grantee)收到的对象权限」,不包括系统权限、角色授权,也不包括该用户自己授予别人的权限 - 导出的是二进制
.dmp文件里的元数据,不是明文 SQL;导入时会自动重放,但无法直接查看或审计
实际迁移时权限怎么处理才可靠?
生产环境最稳妥的做法是「SQL 脚本 + Data Pump 分离处理」:
- 先用上面的三段 SQL 生成
user_A_grants.sql,保存并人工检查(比如确认没漏UNLIMITED TABLESPACE) - 再用
expdp导出用户对象和数据(SCHEMAS=USER_A) - 导入目标库后,先运行
user_A_grants.sql,再导入数据(或反之,但注意:如果先导入数据再赋权,某些触发器/过程可能因权限不足编译失败) - 特别注意:
CREATE SESSION、UNLIMITED TABLESPACE这类基础权限必须显式赋予,expdp和INCLUDE=GRANT都不会覆盖它们
权限不是“附着在用户身上”的实体,而是独立维护的元数据集合——忽略这点,最容易在跨库迁移后遇到「对象存在但无法访问」的问题。


















