段争用(segment header、freelist groups)是buffer busy waits的常见根因,尤其在高并发INSERT场景下,P3=4或P3=130/220配合P1/P2指向段头时基本可确认;需结合dba_segments和dba_extents交叉验证P1/P2是否真为段头或freelist块,并据ASSM或手动管理表空间选择对应优化路径。

段争用(segment header、freelist groups)是buffer busy waits的常见根因,尤其在高并发INSERT场景下,P3=4或P3=130/220配合P1/P2指向段头时基本可确认。
查P3值确认是否为段头争用
buffer busy waits的P3参数直接决定争用类型。段头争用对应固定原因码:P3=4(数据段头)、P3=17(UNDO段头)、P3=18(UNDO块),而P3=130或P3=220需进一步结合块位置判断是否落在段头范围。
执行以下查询获取当前等待会话的P3:
SELECT sid, event, p1 AS file#, p2 AS block#, p3 FROM v$session_wait WHERE event = 'buffer busy waits';
若p3 = 4,基本可断定是数据段头争用;若p3 = 17或18,则聚焦UNDO段配置问题。
用P1/P2定位是否真落在段头或freelist group上
仅看P3不够——必须验证P1/P2对应的块是否确实是段头或freelist管理块。Oracle不保证P3=4时P2一定等于header_block,需交叉查dba_segments和dba_extents。
- 先查该
file#和block#是否匹配某段的header_block:
SELECT segment_name, segment_type, partition_name FROM dba_segments WHERE header_file = &p1 AND header_block = &p2;
- 再查是否落在freelist group区间内(适用于手动管理表空间):
SELECT segment_name, segment_type, freelist_groups FROM dba_segments WHERE header_file = &p1 AND &p2 BETWEEN header_block + 1 AND header_block + freelist_groups;
- 若以上都不命中,但
p2落在dba_extents中某extent的block_id到block_id + blocks - 1范围内,则属于普通数据块争用,不是段头问题。
区分ASSM vs 手动管理表空间的处理路径
段头争用的解决方式完全取决于表空间管理方式,混用会导致误判:
- 如果是ASSM(
segment_space_management = 'AUTO')表空间:P3=4大概率是HWM移动争用,而非freelist。此时应检查是否大量小事务INSERT导致频繁推进HWM,可考虑增大initrans或使用ALTER TABLE ... SHRINK SPACE COMPACT回收空间。 - 如果是手动管理(
segment_space_management = 'MANUAL')表空间:P3=4且p2落在header_block + 1 ~ header_block + freelist_groups区间内,说明是freelist group争用。需增加FREELISTS或FREELIST GROUPS参数,并确保对象创建时显式指定(如STORAGE(FREELISTS 8 FREELIST GROUPS 4))。 - UNDO段头(
P3=17)争用通常意味着UNDO表空间过小或undo_retention设得过高,导致回滚段反复重用;UNDO块(P3=18)争用则多见于长查询与大批量DML时间重叠,需调整undo_retention或拆分大事务。
容易被忽略的释放侧问题
在RAC环境中,gc buffer busy release等待常被当成次要指标,但它可能掩盖真正的瓶颈:比如LMS进程CPU打满或私网延迟高,导致本该快速释放的段头PIN迟迟无法广播出去。此时v$session_wait中state = 'WAITING'且sql_id为空,说明卡在GC消息层,还没进入SQL执行阶段——这种情况下优化SQL毫无意义,必须先查gv$sysstat中gc cr block receive time和gc current block receive time是否异常升高。


















