单纯用expdp导出schema不包含用户权限,因SCHEMAS模式仅导出对象结构而不访问DBA_USERS等权限视图;必须用FULL=Y+CONTENT=METADATA_ONLY+INCLUDE指定USER、ROLE、SYSTEM_GRANT等元数据项才能完整备份用户及权限。
单纯用 expdp 导出 schema(比如 schemas=app_user)不会同步用户权限,包括密码、create session、角色授权、表空间配额等——这些信息不在 schema 对象里,而在数据字典中。必须显式导出元数据,且不能依赖 schemas 参数。
为什么 SCHEMAS 模式导出不带权限
Oracle Data Pump 的 SCHEMAS 模式只扫描该用户拥有的对象(表、索引、过程等),它不访问 DBA_USERS、DBA_SYS_PRIVS、DBA_ROLE_PRIVS 这类全局视图。即使加了 CONTENT=ALL,也只影响表数据或统计信息,不影响账户定义本身。
常见现象:
- 导入后用户存在,但连不上:报
ORA-01031: insufficient privileges或提示没有CREATE SESSION - 用户能连上,但查不了其他用户的表:
SELECT ANY TABLE权限丢了 - 用户默认表空间、临时表空间、profile 都是空的或回退到数据库默认值
用 FULL=Y + METADATA_ONLY 导出用户及权限
这是最直接、最可控的方式。关键点有三个:FULL=Y 是前提(否则 INCLUDE 不生效)、CONTENT=METADATA_ONLY 确保不导数据、INCLUDE 明确限定范围。
执行前确保操作用户有 EXP_FULL_DATABASE(或 DATAPUMP_EXP_FULL_DATABASE)和 CREATE SESSION 权限,且权限是直接授予的,不能通过中间角色继承。
命令示例:
expdp '/ as sysdba' \ FULL=Y \ CONTENT=METADATA_ONLY \ INCLUDE=USER,ROLE,ROLE_GRANT,DEFAULT_ROLE,SYSTEM_GRANT,OBJECT_GRANT,TABLESPACE_QUOTA,PROFILE \ DIRECTORY=DATA_PUMP_DIR \ DUMPFILE=user_perms_20260604.dmp \ LOGFILE=user_perms_20260604.log
说明:
-
INCLUDE=USER:导出CREATE USER语句,含密码哈希(不可逆)、default/temprary tablespace、profile、account status -
ROLE和ROLE_GRANT:导出角色定义及用户被授角色的动作(如GRANT DBA TO app_user) -
SYSTEM_GRANT:导出系统权限,如GRANT CREATE SESSION TO app_user -
OBJECT_GRANT:导出对象权限,如GRANT SELECT ON hr.employees TO app_user -
TABLESPACE_QUOTA:导出配额,如ALTER USER app_user QUOTA UNLIMITED ON users
impdp 导入时注意 remap_schema 和 TRANSFORM=OID:N
如果目标库已有同名用户,且你想把权限导入到另一个用户(比如从 app_old 同步到 app_new),要用 remap_schema;但要注意:若源用户下有基于 OID 的对象(如对象类型、ADT 表),不加 TRANSFORM=OID:N 会导致导入失败或对象损坏。
示例(将权限从 app_old 映射到 app_new):
impdp '/ as sysdba' \ DIRECTORY=DATA_PUMP_DIR \ DUMPFILE=user_perms_20260604.dmp \ LOGFILE=imp_user_perms.log \ REMAP_SCHEMA=app_old:app_new \ TRANSFORM=OID:N
注意:
-
REMAP_SCHEMA在元数据导入中只重写CREATE USER和权限语句里的用户名,不影响已存在的对象 -
TRANSFORM=OID:N必须显式指定,否则 Oracle 默认保留 OID,可能在目标库引发冲突或 ORA-39126 错误 - 导入前确保目标用户不存在,或先
DROP USER app_new CASCADE,否则CREATE USER会报错
ADG 备库上 sysdba 权限不同步的特殊处理
如果你在 ADG 环境中发现主库已 GRANT SYSDBA TO c##user CONTAINER=ALL,但备库查 V$PWFILE_USERS 返回空,这不是 Data Pump 能解决的问题——SYSDBA 权限写在密码文件里,ADG 不同步密码文件内容。
此时必须手动同步密码文件:
- 在主库生成新密码文件:
orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID entries=30 force=y - 将新文件复制到所有备库对应路径(覆盖原文件)
- 重启备库实例(或至少
ALTER SYSTEM CHECKPOINT并刷新内存缓存)
别指望 expdp/impdp 能修复这个,它压根不碰密码文件。


















