ASSM位图块存储数据块使用状态(空闲/半满/全满)的3位码,不存行数据,位于段头后类型为20的受保护块中,普通SQL无法查询,需通过DBMS_SPACE等间接验证。
ASSM位图块到底存什么,为什么不能直接查
oracle在自动段空间管理(assm)下,用位图块(bitmap block)记录数据块的使用状态,但它不是普通表数据,不走sql引擎,select查不到。你试图用dba_extents或dba_segments反推位图位置,会发现它们只暴露逻辑结构,不暴露物理位图布局。
真正存储位图信息的是段头(Segment Header)之后的几个特殊数据块,类型为type#=20(在X$KTFBUE或BBED中可见),但这些块被Oracle内部保护,普通用户无权读取,强行解析容易导致实例报错ORA-00600。
- 位图块本身不存行数据,只存“某块是否空闲/半满/全满”的3位状态码
- 每个位图块管理约128个数据块(具体取决于
INITIAL和EXTENT MANAGEMENT设置) -
ALTER TABLE ... MOVE或SHRINK SPACE会重写位图块,但不会触发LOGGING,所以归档日志里看不到变化
怎么判断当前段是不是真正在用ASSM
别只看表空间属性——DBA_TABLESPACES.SEGMENT_SPACE_MANAGEMENT = 'AUTO'只是前提,不代表每个段都启用ASSM。关键要看段头块的ktfbhflg标志位,而这个只能通过DBMS_SPACE.SPACE_USAGE或底层视图间接验证。
最稳的方式是查DBA_SEGMENTS配合DBA_TABLES:如果SEGMENT_TYPE = 'TABLE'且对应表的TABLESPACE_NAME启用了ASSM,那它大概率是,但仍有例外——比如用CREATE TABLE ... SEGMENT CREATION DEFERRED建的表,初始没分配段,也就没位图块。
- 执行
DBMS_SPACE.SPACE_USAGE时传入segment_owner、segment_name、segment_type,返回的unformatted_blocks等字段非空,说明ASSM已实际参与管理 -
ALTER TABLE ... ALLOCATE EXTENT后才真正生成位图块,此前INSERT可能失败并报ORA-01653 - 索引组织表(IOT)的溢出段(overflow segment)默认禁用ASSM,即使表空间是AUTO,也要显式指定
INCLUDING子句才能联动
位图块争用导致的enq: TX - allocate ITL entry怎么定位
这不是ITL本身不够,而是多个会话同时尝试从同一个位图块申请新数据块时卡住。典型现象是AWR里enq: TX等待突增,且P1值恒为1415073539(即TX-4),P2显示的是位图块的DBA(如0x0100a2f3)。
这时候查V$SESSION_WAIT或ASH,过滤EVENT = 'enq: TX - allocate ITL entry',再用DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE和DATA_BLOCK_ADDRESS_BLOCK拆解P2,就能定位到具体哪个位图块成了瓶颈。
- 高并发插入小行数据(如日志表)最容易触发,因为每次插入都可能需要新块,频繁访问同一组位图块
- 解决方向不是加
INITRANS,而是调整PCTFREE让单块容纳更多行,或拆分段(如按时间分区)分散位图压力 -
DB_CACHE_SIZE过小会导致位图块反复进出Buffer Cache,加剧latch争用,观察cache buffers chains等待可佐证
SEGMENT CREATION IMMEDIATE和DEFERRED对位图块的影响
区别不在“有没有位图”,而在“位图块什么时候落地”。IMMEDIATE会在CREATE TABLE时就分配首个extent、写入段头、初始化位图块;DEFERRED则完全跳过这步,直到第一次INSERT或ALLOCATE EXTENT才创建。
这意味着:用DEFERRED建的表,在DBA_SEGMENTS里查不到记录,DBMS_SPACE.SPACE_USAGE直接报ORA-32004,连位图块的影子都没有。但一旦插入一行,所有ASSM机制立刻激活,包括位图更新、空闲块链表维护、甚至可能触发隐式EXTEND。
-
DEFERRED能省下初始空间,但首次DML延迟明显,尤其在大表空间里,分配首个extent可能卡几百毫秒 - 用
DBMS_SPACE.UNUSED_SPACE查DEFERRED表会返回0,不是bug,是设计如此 - 导出导入(
EXPDP)默认保留DEFERRED属性,但如果目标库版本低(如11.2之前),可能强制转成IMMEDIATE,位图行为就变了
位图块不是黑盒,但它的生命周期藏在段分配动作里,而不是DDL语句里。改一个参数、换一种建表方式,位图块的生成时机和压力分布可能完全不同——这点在压测和上线前最容易被忽略。










