exp工具会静默跳过SEGMENT_CREATED='NO'的空表,因其仅扫描USER_SEGMENTS视图;Oracle 11g默认启用deferred_segment_creation,新建空表不分配段,故USER_TABLES中SEGMENT_CREATED为'NO';唯一可靠判断字段是SEGMENT_CREATED,需用ALTER TABLE...ALLOCATE EXTENT修复。

exp 工具会静默跳过所有 SEGMENT_CREATED = 'NO' 的表,不报错、不警告、也不写日志——你拿到的 DMP 文件看起来完全正常,但导入后结构就永远少几张表。
为什么 exp 看不见这些空表
Oracle 11g 默认启用 deferred_segment_creation=TRUE,新建空表时根本不分配物理段(segment),USER_TABLES.SEGMENT_CREATED 字段值为 'NO'。而 exp 只扫描 USER_SEGMENTS 视图里存在的对象,它压根不查 USER_TABLES 中那些没 segment 的表。
-
NUM_ROWS = 0不可靠:统计信息可能未更新,NUM_ROWS是NULL或旧值,不能当筛选依据 - 真正唯一可信的状态字段只有
SEGMENT_CREATED,查它才准 - 系统用户(如
SYS、SYSTEM)下的表不受该特性影响,始终分配 segment
如何快速定位并修复问题表
在目标用户下执行这条 SQL,直接列出所有被 exp 忽略的表:
SELECT TABLE_NAME FROM USER_TABLES WHERE SEGMENT_CREATED = 'NO';
生成修复语句并执行:
SELECT 'ALTER TABLE ' || TABLE_NAME || ' ALLOCATE EXTENT;' FROM USER_TABLES WHERE SEGMENT_CREATED = 'NO';
- 每条
ALTER TABLE ... ALLOCATE EXTENT执行后,SEGMENT_CREATED立即变为'YES' - 不需要插入/删除数据,不触发触发器、约束或审计日志
- 普通用户只要拥有该表的
ALTER权限就能执行,无需 DBA 权限 - 别用
INSERT + ROLLBACK:看似简单,但可能意外激活业务逻辑
expdp 能导出空表,但真能替代 exp 吗
expdp 确实不受 deferred_segment_creation 影响,会导出所有表元数据,但它不是“一键替换”方案:
- 必须先由 DBA 创建并授权
DIRECTORY对象,普通用户无法自行完成 - 需要
EXP_FULL_DATABASE或EXP_DATAPUMP_USER_ROLE角色,权限模型更重 -
exp的参数(如OWNER=、TABLES=)和脚本逻辑与expdp不兼容,自动化流程要重写 - 很多生产环境因权限锁定或工具链固化,根本切不动
expdp
所以真正能立刻落地、风险最低的动作,还是那几行 ALTER TABLE ... ALLOCATE EXTENT ——它不改变数据库配置,不依赖额外权限,只动目标表本身。
最麻烦的不是操作多难,而是这个状态完全隐形:SEGMENT_CREATED = 'NO' 在日常查询里几乎不会被注意,直到导出失败后反复比对表清单才发现缺了谁。导出前顺手跑一遍检查,比事后排查快十倍。


















