必须用sys或具有administer database trigger权限的用户(如as sysdba)执行dbms_tts.transport_set_check,普通用户会报pls-00201错误;表空间名需全大写、逗号分隔无空格,full_check设为true才检查外键等深层依赖,结果通过transport_set_violations视图查看,非空即表示不自包含,须修复逻辑冲突(如跨表空间约束、system中非系统用户对象等),且检查通过后仍需将表空间设为read only方可导出。

dbms_tts.transport_set_check 执行权限和连接用户问题
必须用 SYS 或具有 ADMINISTER DATABASE TRIGGER 权限的用户(通常是 AS SYSDBA)执行,普通用户或非特权账号调用会报 PLS-00201: must declare identifier 'DBMS_TTS.TRANSPORT_SET_CHECK'。常见错误是直接用业务用户连上去就跑 exec dbms_tts.transport_set_check,结果失败。
实操建议:
- 先
connect / as sysdba,再执行检查 - 表空间名区分大小写,且需全大写传入(如
'USERS',不是'users') - 多个表空间用英文逗号分隔,不加空格:
'USERS,EXAMPLE,INDX' - 第二个参数
full_check设为true才会检查外键、索引、分区依赖等深层关系
transport_set_violations 视图里常见 ORA 错误含义
SELECT * FROM transport_set_violations; 返回非空结果,说明表空间不自包含。每条记录对应一个违反项,典型错误包括:
-
ORA-39921:某张表的默认分区位于SYSTEM表空间,但你没把它加进传输集 -
ORA-39906:外键约束跨表空间,比如主表在ORCLTBS,从表在SYSTEM -
ORA-39908:主键索引在SYSTEM,但表本身在目标表空间 -
ORA-39911:本地索引指向了不在传输集里的分区(尤其常见于分区表)
注意:这些错误不是“语法错”,而是数据逻辑冲突,必须修复后才能继续传输——要么把关联对象一并加入传输表空间,要么重建索引/约束到目标表空间。
分区表和 SYSTEM 表空间混用是最大雷区
很多迁移失败根源在于非系统用户对象(user_id > 84)意外落在 SYSTEM 或 SYSAUX 里,尤其是分区表的分区段、索引段、LOB 段。
快速定位命令:
SELECT owner, segment_name, partition_name, segment_type
FROM dba_segments
WHERE tablespace_name IN ('SYSTEM', 'SYSAUX')
AND owner NOT IN (SELECT username FROM dba_users WHERE user_id <p>如果查出结果,说明这些对象必须先迁移走,否则 <code>transport_set_check</code> 必然失败。不能靠“忽略警告”硬传,Oracle 在导入阶段会直接报错退出。</p><h3>自包含检查通过后仍要确认 read only 状态</h3><p>检查通过只代表结构上没问题,不代表能立刻导出。下一步必须执行 <code>ALTER TABLESPACE xxx READ ONLY</code>,否则 <code>exp</code> 或 <code>expdp</code> 会因数据变动导致一致性校验失败。</p>
- 执行前确认无活跃事务写入该表空间(查
v$transaction和v$session) - 如果是 RAC 环境,所有实例都得看到该表空间为
READ ONLY,可用SELECT status FROM dba_tablespaces验证 - 别忘了后续还要
ALTER TABLESPACE xxx READ WRITE,否则业务会中断
真正卡住人的往往不是检查本身,而是检查通过后忘了切只读,或者切了但没验证是否生效——这会导致导出耗时暴涨甚至失败,而错误日志里只显示“consistent read failed”,不提根本原因。











