Oracle 19c默认启用延迟段创建,参数DEFERRED_SEGMENT_CREATION为TRUE;可通过SHOW PARAMETER deferred_segment_creation确认,修改需重启实例,仅影响新建对象,不支持SYS用户、SYSTEM表空间、IOT等场景。
oracle 19c 默认启用延迟段创建,无需额外设置 —— 只要表不是在 sys/system 等受限用户下、不在 system 表空间或字典管理表空间中,且不是 iot/临时表等不支持类型,create table 就自动按 deferred 行为执行。
怎么确认当前数据库是否启用延迟段创建
虽然 DEFERRED_SEGMENT_CREATION 是隐含参数,但 19c 中它已转为公开初始化参数,可用标准方式查询:
SHOW PARAMETER deferred_segment_creation
返回 TRUE 即表示启用(默认值);若为 FALSE,则所有新建空表都会立即分配段。
注意:该参数只影响新创建的对象,已有表不受影响。修改后需重启实例才生效(SCOPE=SPFILE),不能热改。
建表时显式控制段创建时机
即使参数为 TRUE,你仍可在 CREATE TABLE 语句中用 SEGMENT CREATION 子句覆盖默认行为:
-
SEGMENT CREATION DEFERRED:强制延迟(与参数一致,冗余但明确) -
SEGMENT CREATION IMMEDIATE:跳过延迟,建表即分配初始 extent
示例:
CREATE TABLE t1 (id NUMBER) SEGMENT CREATION DEFERRED; -- 空表不出现在 USER_SEGMENTS
CREATE TABLE t2 (id NUMBER) SEGMENT CREATION IMMEDIATE; -- 立即出现在 USER_SEGMENTS
常见错误:漏写 SEGMENT CREATION 后直接跟 TABLESPACE,会报 ORA-00922(缺失关键字)。正确顺序是:... SEGMENT CREATION IMMEDIATE TABLESPACE users。
哪些表/场景不支持延迟段创建
以下情况即使参数为 TRUE,Oracle 也会忽略延迟,直接建段:
- 用户为
SYS、SYSTEM、OUTLN、XDB、PUBLIC - 表空间为
SYSTEM或字典管理表空间(DMT) - 表类型为:索引组织表(IOT)、簇表、全局临时表、外部表、AQ 表、Typed 表
- 包含位图连接索引或域索引
- 分区表的主表虽可延迟,但子分区若未显式指定
SEGMENT CREATION DEFERRED,可能因父表策略不一致而意外建段
验证方法:查 USER_TABLES.segment_created 字段,'NO' 表示尚未建段;'YES' 表示已建段。
为什么刚建的空表在备份或工具里“消失”了
这是延迟段最常踩的坑:很多工具依赖 DBA_SEGMENTS 或 USER_SEGMENTS 判断对象是否存在,而延迟段表在插入前不会出现在这些视图中。
典型现象:
-
exp(旧版导出)完全跳过未建段的表,导致恢复后表结构丢失 -
Data Pump expdp能导出结构(因读数据字典),但若没加CONTENT=ALL或未显式INCLUDE=TABLE,仍可能遗漏 - OGG(GoldenGate)抽取进程可能忽略空表,同步启动后才发现目标端少表
- 监控脚本用
COUNT(*) FROM user_segments统计“活跃表数”,结果偏低
临时补救:对已存在但未建段的表,执行 ALTER TABLE t ALLOCATE EXTENT; 或插一条再删(INSERT ...; COMMIT; DELETE; COMMIT;),即可触发段分配。
真正容易被忽略的是:延迟段不是“功能开关”而是“空间契约”——它把段分配从“建表时”推迟到“首次写入时”,但这个“首次”可能永远不来。DBA 和开发得共同约定:空表是否应被视作有效对象?如果答案是肯定的,那就别依赖默认延迟,要么改参数,要么显式写 IMMEDIATE,否则工具链和监控就总在边缘试探。


















