oracle 19c默认推荐但不自动启用assm,必须显式指定segment space management auto才生效;漏配将退化为mssm引发争用,且表空间属性不可修改,需通过move或expdp迁移对象并预热段。
oracle 19c 默认启用 assm,但仅当表空间创建时显式指定 segment space management auto 才真正生效;不配置或误配会导致高并发下出现 enq: tx - allocate itl entry 或 buffer busy waits。
创建表空间时必须显式开启 ASSM
本地管理表空间(LMT)是前提,但 SEGMENT SPACE MANAGEMENT AUTO 不是默认值——即使 Oracle 19c 推荐 ASSM,仍需手动声明。漏写这句,段会退化为 MSSM,Freelist 争用照旧。
- 正确写法:
CREATE TABLESPACE tbs_app DATAFILE '/u01/oradata/ORCL/tbs_app01.dbf' SIZE 500M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO; - 错误写法:省略
SEGMENT SPACE MANAGEMENT AUTO,或写成MANUAL;哪怕表空间是 LMT,段空间管理仍为手动 - 验证命令:
SELECT tablespace_name, segment_space_management FROM dba_tablespaces WHERE tablespace_name = 'TBS_APP';——结果必须为AUTO
已有表空间无法直接“升级”为 ASSM
表空间的 SEGMENT_SPACE_MANAGEMENT 属性不可修改。想让现有对象用上 ASSM,只能迁移,不是 ALTER 命令能解决的。
- 方案一(推荐):新建 ASSM 表空间,再用
ALTER TABLE ... MOVE TABLESPACE new_tbs迁移表;索引需重建:ALTER INDEX ... REBUILD TABLESPACE new_tbs - 方案二:导出/导入(
expdp/impdp),指定REMAP_TABLESPACE - 注意:
ALTER TABLESPACE ... READ ONLY后不能做MOVE;且MOVE期间表不可写,需安排维护窗口
ASSM 生效 ≠ 段立即有位图块
刚创建的空表(尤其 SEGMENT CREATION DEFERRED 默认启用时)没有分配段,也就没有位图块。首次插入触发 ALLOCATE EXTENT 后,ASSM 才真正介入空间分配。
- 现象:空表查
DBA_SEGMENTS查不到记录;执行INSERT后才出现,且第一次 INSERT 可能报ORA-01653(如果初始 extent 分配失败) - 主动预热:用
ALTER TABLE t ADD STORAGE (INITIAL 1M);或ALTER TABLE t ALLOCATE EXTENT;强制生成段和 L1 位图块 - 关键点:IOT 的溢出段(overflow segment)默认禁用 ASSM,即使主表在 AUTO 表空间,也得显式加
INCLUDING子句才能联动启用
高并发插入场景要防 L1 位图块争用
ASSM 把争用从段头分散到多个 L1 位图块,但若所有会话都往同一组数据块插(如单字段自增 ID + 小行),仍可能卡在同一个 L1 BMB 上。
- 定位瓶颈:
SELECT event, p1, p2, p3 FROM v$session_wait WHERE event = 'enq: TX - allocate ITL entry';若p1 = 1415073539,说明是位图块争用;用DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(p2)和DATA_BLOCK_ADDRESS_BLOCK(p2)解出具体 DBA - 缓解手段:增大
INITIAL大小(至少 3 块起),避免频繁分配新 extent;对日志类表,考虑按时间分区 + 每个分区独立段,天然分散位图压力 - 别碰底层:位图块类型为
type#=20,受 Oracle 内部保护,SELECT查不到,BBED强读可能引发ORA-00600,不建议尝试
ASSM 的核心价值不在“开了就完事”,而在于让位图块真实承载写入压力。最容易被忽略的是:表空间属性只是开关,段是否真用位图,取决于它有没有被分配、有没有被写入、以及写入模式是否把压力打在同一组 L1 块上。











