expdp/impdp 不能直接迁移用户到19c并确保权限、角色、密码策略全部生效,因字符集、密码版本、默认表空间隐式继承、对象权限依赖链等细节易导致ORA-39346、ORA-01918或登录失败。
不能用 expdp 直接迁移用户到 19c 并期望权限、角色、密码策略全部生效——字符集、密码版本、默认表空间隐式继承、对象权限依赖链这些细节会集体“叛变”,最常卡在 ora-39346、ora-01918 或登录失败。
expdp/impdp 迁移时密码和认证方式不兼容
11g 默认使用 11G 密码版本(SQLNET.ALLOWED_LOGON_VERSION_SERVER=8),而 19c 默认只接受 12A 及以上版本。直接导入后,用户能查到但无法登录。
- 导出前在 11g 源库确认密码版本:
SELECT username, password_versions FROM dba_users WHERE username = 'TESTUSER'; - 导入后在 19c 目标库必须重置密码并显式指定版本:
ALTER USER testuser IDENTIFIED BY VALUES 'S:...';(从源库dba_users中复制加密值)或更稳妥地:ALTER USER testuser IDENTIFIED BY newpass ACCOUNT UNLOCK; - 若需保留旧密码格式兼容,临时在 19c 设置:
ALTER SYSTEM SET SQLNET.ALLOWED_LOGON_VERSION_SERVER=11 SCOPE=BOTH;,但仅限迁移过渡期,不可长期开启
权限与角色导入后失效的常见原因
不是 impdp 没导出权限,而是目标库缺少依赖对象或上下文不匹配:比如源库有 GRANT SELECT ON SYS.V_$SESSION TO testuser,但 19c 中该视图已重命名为 V$SESSION,且底层对象权限模型变更。
- 务必用
CONTENT=METADATA_ONLY先试导元数据,检查日志中是否出现ORA-39112(被跳过的 DDL)或ORA-39126(内部包错误) - 避免用
SCHEMAS模式全量导入——它会忽略SYSTEM级权限(如CREATE SESSION)。改用INCLUDE=GRANT,ROLE_GRANT,DEFAULT_ROLE显式控制 - 导入后立即运行:
SELECT grantee, privilege, owner, table_name FROM dba_tab_privs WHERE grantee = 'TESTUSER' AND (owner, table_name) NOT IN (SELECT owner, object_name FROM dba_objects);—— 找出指向不存在对象的权限,手动清理或重建
默认表空间和临时表空间的“静默漂移”
11g 用户创建时若未显式指定 TEMPORARY TABLESPACE,会继承数据库默认临时表空间;但 19c 的 DEFAULT TEMPORARY TABLESPACE 可能是 PDB$SEED 下的新临时表空间,导致导入后用户实际绑定的是空或不可写表空间,首次排序就报 ORA-01652。
- 导出前查源库配置:
SELECT property_name, property_value FROM database_properties WHERE property_name LIKE '%TABLESPACE%'; - 导入后立刻校验:
SELECT username, default_tablespace, temporary_tablespace FROM dba_users WHERE username = 'TESTUSER'; - 若
temporary_tablespace是TEMP$SEED或为空,立即修正:ALTER USER testuser TEMPORARY TABLESPACE temp;(确保目标库存在同名且可写的临时表空间)
真正麻烦的从来不是命令敲错,而是那些没报错却悄悄失效的隐式依赖:比如某个 SYNONYM 指向已删除的包、某个 PROFILE 在 19c 中参数含义已变、甚至 NLS_LANGUAGE 设置不同导致 TO_DATE 解析失败。迁移后至少跑一遍关键业务 SQL,别只信 STATUS=VALID。


















