Oracle 21c中STORAGE子句常被忽略或报错,因其默认启用ASSM和LMT,导致INITIAL、NEXT、PCTINCREASE、MINEXTENTS、MAXEXTENTS、FREELISTS及FREELIST GROUPS等参数彻底失效且被静默忽略;仅IOT溢出段、非ASSM表空间(如SYSTEM)或NOLOGGING批量加载等极少数场景仍需显式指定,但属反模式或临时行为。
Oracle 21c中STORAGE子句为什么常被忽略或报错?
因为 oracle 21c 默认启用自动段空间管理(assm)和系统管理的存储策略,手动指定 initial、next、pctincrease 等参数不仅无效,还可能触发警告甚至拒绝建表。你执行 create table t (x int) storage (initial 64k) 后查 dba_tables,会发现 initial_extent 字段仍是系统默认值(如 1mb),而非你写的 64k。
哪些STORAGE参数在21c中彻底失效?
以下参数在 ASSM 表空间中完全被忽略,数据库启动时不会报错,但也不生效:
-
MINEXTENTS和MAXEXTENTS:Oracle 21c 使用本地管理表空间(LMT),extent 分配由位图控制,这两个参数已无意义 -
PCTINCREASE:仅适用于字典管理表空间(DMT),而 21c 安装即强制 LMT,该参数语法虽保留,实际不参与 extent 计算 -
FREELISTS/FREELIST GROUPS:ASSM 下由位图块自动管理空闲空间,手工设置会被静默丢弃
什么场景下仍需显式写STORAGE?
极少数情况例外,但必须明确知道后果:
- 创建索引组织表(IOT)时,
OVERFLOW段仍支持STORAGE子句,用于控制溢出段的初始分配(但主键段本身仍走 ASSM) - 在非 ASSM 表空间(如 SYSTEM 表空间)中创建对象——但这属于反模式,21c 中不应主动往 SYSTEM 写业务对象
- 使用
NOLOGGING+STORAGE组合做一次性大批量加载(如 Data Pump 导入时指定TRANSFORM=STORAGE:n),此时STORAGE仅影响临时段分配行为,不影响最终段结构
替代方案:用什么真正控制空间行为?
21c 推荐用更上层、更语义化的机制替代低阶 STORAGE 控制:
- 用
SEGMENT CREATION DEFERRED(默认)延迟段创建,避免空表占空间;设为IMMEDIATE才立即分配首个 extent - 通过
ALTER TABLE ... MOVE LOB(...)显式重定位 LOB 段,并指定STORE AS SECUREFILE+COMPRESS HIGH控制实际物理布局 - 对频繁增删的表,启用
INMEMORY或HEAT MAP+Automatic Data Optimization (ADO),让数据库根据访问热度自动压缩/迁移冷数据,比手调NEXT更有效
最易被忽略的一点:即使你在 DDL 中写了完整 STORAGE,只要目标表空间是 LMT+ASSM(21c 全部默认如此),这些参数就只是“注释级存在”——它们进不了数据字典,也不会出现在 DBA_SEGMENTS 或 V$SEGSTAT 中。真要验证空间行为,得看 DBA_EXTENTS 的实际分配记录,而不是 DDL 文本。


















