buffer busy waits 的 p3 值为 4 表示段头争用,p3=130 或 220 对应 assm 下 l1/l2 位图块争用,需结合 dba_extents 区间匹配验证块归属,并通过 sql_opname='insert'、session_state='on cpu' 及业务 module 过滤真实会话。

查 buffer busy waits 的 P3 值确认是否段头争用
高并发 INSERT 最常见的空间争用表现就是 buffer busy waits,但不能只看事件名——关键在 P3。P3 = 4 表示块类型是 segment header,基本锁定为段头争用;P3 = 130 或 220 则对应 ASSM 下的 L1/L2 位图块争用。必须结合 current_file# 和 current_block# 查 DBA_EXTENTS,验证该块是否真属于目标表的段头或位图块,而不是误判为普通数据块。
用 current_obj# + sql_opname = 'INSERT' 过滤真实业务会话
别只筛 sql_id,很多 INSERT 是批量作业或微服务触发的匿名 PL/SQL,sql_id 可能为 0000000000000000 或不可见。更稳的方式是:
-
session_state = 'ON CPU'且sql_opname IN ('INSERT') event IN ('buffer busy waits', 'enq: TX - index contention', 'enq: TW - contention')-
program或module匹配业务标识(如'BatchInserter'、'UserService')
这样能避开递归 SQL 干扰,直击真正发起 INSERT 的前台会话。
区分 MSSM 和 ASSM 下的优化路径
MSSM(手动段空间管理)下 P3 = 4 意味着 FREELIST 争用,解决方向是增加 FREELISTS 和 FREELIST GROUPS;ASSM 下 P3 = 130/220 则说明 L1/L2 位图块热,此时加 FREELIST 没用,得考虑:
- 改用
ASSM + AUTOALLOCATE(避免手工指定 INITIAL/FREELISTS) - 对高频插入表启用
SEGMENT CREATION DEFERRED(防空表段头被提前争用) - 拆分大表为分区表,让 INSERT 分散到不同子段(尤其按时间/租户分区)
注意:ALTER TABLE ... MOVE 不会自动重建位图结构,需后续 DBMS_SPACE_ADMIN.SEGMENT_CORRUPT_BLOCKS 配合 SHRINK SPACE 才能释放旧位图块压力。
别跳过 dba_extents 的区间匹配逻辑
把 current_block# 映射到对象时,必须用 BETWEEN block_id AND block_id + blocks - 1,不是 = block_id。因为一个数据块只属于一个 extent,但一个 extent 可能跨多个 segment(比如分区表的某个子分区),直接等值查会漏掉真实归属。若查不到结果,该块大概率属于系统段(UNDO、temp、回滚段),这时要转向 v$rollstat 或 v$tempseg_usage 排查。











