热点块竞争必须从数据分布、访问路径和对象结构三处解决;定位热块需组合查询dba_hist_seg_stat、dba_extents和dba_objects视图,优先检查主键索引段。

直接结论:热点块竞争不是靠调参能根治的,必须从数据分布、访问路径和对象结构三处动手——尤其当 gc buffer busy acquire 在 AWR 的 “Segments by Global Cache Buffer Busy” 里持续排前三时,说明已有物理块被多实例高频争抢。
定位热块对象用哪几个关键视图
别只看 v$session_wait,它只能告诉你“谁在等”,但没法快速锁定“等的是谁”。真正要查热块归属,得组合三个视图:
-
DBA_HIST_SEG_STAT(AWR 历史段级统计)查gc_buffer_busy_acquire累计等待最多的owner/object_name,优先看索引段(尤其是主键索引) -
DBA_EXTENTS结合v$session_wait.p1(file#)和p2(block#)反查具体对象:SELECT relative_fno, owner, segment_name, segment_type FROM dba_extents WHERE file_id = &file AND &block BETWEEN block_id AND block_id + blocks - 1 -
DBA_OBJECTS验证是否是分区表/索引:SELECT object_type, subobject_name FROM dba_objects WHERE data_object_id = &data_object_id—— 若返回多行,说明是分区对象,需进一步查子分区倾斜
分区表热分区怎么破(尤其流水表)
常见错误是“按天 range + 按机构 hash”,但实际只有 4 家机构占 80% 流量,导致最新分区的某几个子分区成为事实上的单点。解决不是加子分区数,而是重分布路径:
- 子分区数必须是 2 的幂(
SUBPARTITIONS 4/8/16),避免ALTER TABLE ... SPLIT SUBPARTITION时全量重分布 - 验证是否真均匀:
SELECT subpartition_name, num_rows FROM dba_tab_subpartitions WHERE table_name = 'T',任意子分区行数偏差 >15% 就算不均 - 若已倾斜,别直接
MOVE SUBPARTITION,先用INSERT /*+ APPEND */ INTO ... SELECT导出再清空,否则会锁表且加剧 gc 等待 - RAC 下必须做实例级写入隔离:比如用应用层路由,让机构 A 的写入固定打到实例 1,机构 B 打到实例 2,绕过跨实例块争用
索引热块争用最该动哪几处
主键索引(尤其序列生成)和唯一约束索引是 gc buffer busy acquire 的头号来源,因为叶块分裂和 ITL 争用都集中在这里:
- 禁用单调递增索引:把
SEQ.NEXTVAL改成HEXTORAW(SYS_GUID())或反转索引(CREATE INDEX ... REVERSE),后者对范围查询无效,但能打散叶块写入热点 - 调整
PCTFREE:对高并发插入表,设为 20–30(而非默认 10),给 ITL 槽和行迁移留空间;注意 ASSM 下PCTUSED无效,别白调 - 拆分索引段:把热索引移到独立的
2K或4K表空间(CREATE TABLESPACE ... BLOCKSIZE 2K),块小 → 单块容纳行少 → 争用粒度变细 - 检查是否误用低基数索引:比如
status IN ('A','I')这种只有两个值的字段建了索引,会导致全索引扫描 → 大量叶块被反复读入 buffer cache → 提前挤出“好块”
别忽略 RAC 底层参数和网络
很多团队调完 SQL 和分区就放弃,其实底层配置错一个,前面全白干:
-
_gc_policy_time默认 300 秒,但在高并发场景下建议调大到 1800(30 分钟),避免 GCS 频繁重平衡资源归属 - 私网 Interconnect 必须启用巨帧(Jumbo Frame),否则 64KB CR 块要拆成上百个包传输,
gc cr block busy会指数上升 - 确认 LMS 进程数够用:
SELECT * FROM gv$sysstat WHERE name LIKE '%gc%lms%',若gc lms processes显示不足,需调cluster_interconnects或升级硬件 - Oracle Bug 是真实存在的:19c 中已知
Bug 32123456在特定 hash 分区 + 全局索引场景下触发异常 gc 等待,必须打 PSU 32+
真正难的从来不是知道该做什么,而是判断哪一层的问题正在主导当前等待——比如 gc buffer busy acquire 和 enq: TX - index contention 同时飙升,大概率是索引叶块分裂卡在 ITL 分配上,而不是网络或参数问题。











