local索引能缓解gcs争用,因其天然绑定分区,各节点仅管理本分区索引段,避免跨节点全局锁协调;而global索引在rac下是单点瓶颈,高并发dml易引发gc buffer busy acquire等待飙升。
为什么local索引能缓解gcs争用
global index在rac下是单点瓶颈:任何dml操作都会触发跨节点的索引块争用,尤其高并发插入时,gc buffer busy acquire等待会飙升。而local index天然绑定分区,每个节点只管理自己分区的索引段,避免了全局锁协调。
新建分区表时,默认用LOCAL,别图省事写GLOBAL。已有GLOBAL INDEX要改造?先确认索引列是否和分区键存在函数依赖,否则重建后可能无法做分区裁剪。
-
LOCAL INDEX无法支持跨分区唯一约束——需要全局唯一时,得靠应用层或触发器兜底 - 重建前查
dba_indexes确认partitioned字段为YES,再用dba_ind_partitions核对各分区状态 - 重建过程会阻塞DML,建议在低峰期用
ONLINE选项(12c+支持)
分区键选错会放大GCS争用
按user_id这类业务主键直接分区,极易导致热点集中在少数节点。比如所有user_id为奇数的请求都落到node1,引发频繁的跨节点块传输。
根本问题不在分区本身,而在分区键与访问模式耦合太紧。优先选高基数、访问分散的字段:
- 用
MOD(ORA_HASH(order_id), 64)生成伪随机分区号,再配合RANGE或LIST落地 - 避免单独用
tenant_id或region_code——除非你确认每个租户/区域的数据量和访问频次高度均衡 - 时间字段如
created_at适合范围分区,但需搭配查询习惯(例如常查最近7天,则按日/周分区更有效)
如何验证索引和数据真正在节点间打散了
光看DBA_TAB_PARTITIONS里的HIGH_VALUE没用,得查实际数据分布。RAC里最直接的证据是各节点的gc cr block received和gc current block received指标是否趋近平衡。
每小时自动在推特搜索中国、加密货币、国际热点、美国热点、特朗普等话题的热度信息,提取前十热点,依据 X 平台真实算法权重(开源代码数据)为每个热点生成高曝光推文或线程。用户提及“推特热点”“Twitter热点”“推特搜索”“热点推文”“生成推文”“社交媒体监控”“Twitter监控”等关键词时触发。
执行:SELECT inst_id, COUNT(*) FROM your_table GROUP BY inst_id;——如果某节点结果占比超60%,说明打散失败。
- 查
V$PX_SESSION确认并行查询是否均匀分配到各实例;若总看到INST_ID = 1占多数,大概率是分区键或并行度设置有问题 - 用
DBMS_ROWID.ROWID_BLOCK_NUMBER抽样一批ROWID,再查V$BH确认这些块是否分布在不同实例的buffer cache中 - 注意
V$BH中INST_ID字段才是块所在节点,不是OWNER或OBJECT_NAME
INSERT /*+ APPEND */在RAC下的隐性陷阱
APPEND直通路径写入虽快,但在RAC下会强制使用NOLOGGING+LOCAL分配,导致新数据全堆在当前节点的默认临时段,反而制造新的热点。
批量导入时,显式指定分区:INSERT INTO t PARTITION (p202401) SELECT ...,让数据落点可控。
- 禁用
APPEND不是万能解法——它会让事务变长、undo压力大,需权衡吞吐与一致性要求 - 如果必须用
APPEND,提前在每个节点上运行ALTER TABLE t ALLOCATE EXTENT,预分配空间,减少运行时争用 -
APPEND不走UNDO,但会触发gc current block 2-way事件,若目标分区段未预热,仍会引发瞬时GCS争用
真正难的不是建LOCAL索引或换分区键,而是把应用访问路径、数据生命周期、节点负载能力三者对齐。一个没被监控覆盖的enq: TX - row lock contention,可能比十次gc buffer busy acquire更早压垮系统。










