直接调大cache值并强制指定noorder是解决rac下enq: sq-contention的最有效手段;默认cache 20在多节点并发下易耗尽,引发高频跨节点同步等待,加noorder才能使cache生效。
直接调大 cache 值并强制指定 noorder,是解决 rac 下高并发插入卡在 enq: sq - contention 的最有效手段——其他优化(如索引、redo、undo)都得先让序列不拖后腿。
为什么默认 CACHE 20 在 RAC 里会崩
Oracle 默认建序列时设 CACHE 20,意味着每个实例最多缓存 20 个号;RAC 多节点并发下,这 20 个号可能几毫秒就耗尽。一旦用完,所有实例就得抢着去更新系统基表 SEQ$ 并申请 DFS 锁协调分配,引发高频跨节点同步等待。
常见现象包括:
-
SELECT seq_name.NEXTVAL FROM DUAL响应时间毛刺明显,尤其在批量导入启动瞬间 -
v$enqueue_stat中SQ或SVS等待事件飙升 - AWR 报告里
enq: SQ - contention占 DB Time 超过 10%
实测对比:RAC 双节点各插入 4 万个记录,NOCACHE 耗时 2100 秒,CACHE 1000 仅需 55 秒——差 38 倍。
CACHE 值设多少才合理
CACHE 不是越大越好,它本质是在「减少物理读」和「降低崩溃丢失量」之间做权衡,RAC 还要叠加节点间号段粒度问题。
推荐范围与依据:
- 普通业务:50–500,例如每秒 200 条 insert、每批 50 条,
CACHE 200可支撑 1 秒内无跨节点协调 - 超高压场景(如实时计费):可设到 1000,但避免盲目上万——
CACHE 10000+ORDER反而会让一个实例独占号段,其他节点干等 - 注意:
CACHE值写入数据字典后,实例宕机时未用完的号段会丢失(比如CACHE 100,已用 85,剩 15,重启后跳过),这不是 bug,是设计行为
必须加 NOORDER,否则 CACHE 几乎白设
RAC 下 ORDER 模式强制全局有序,每次号段切换都要跨节点确认“你没用过这个值”,走的是高开销的全局队列(如 SVS)。哪怕开了 CACHE 1000,只要没加 NOORDER,就仍是“伪缓存”。
加了 NOORDER 后:
-
v$lock和v$enqueue_stat中SQ类等待几乎归零 -
gv$sequence显示各实例的LAST_NUMBER差距可达几百上千(正常) - 副作用:生成的 ID 不再全局严格递增(如实例 1 出 101–200,实例 2 同时出 201–300,但网络延迟可能导致 201 先入库)
绝大多数业务(订单 ID、日志流水号)不需要严格递增,只依赖唯一性——这是 NOORDER 安全使用的前提。
创建高性能 RAC 序列的最小安全模板
不要对已有序列用 ALTER SEQUENCE 改 CACHE,它不会改变 ORDER/NOORDER 属性;新建时一步到位:
CREATE SEQUENCE s1 INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE CACHE 1000 NOORDER;
验证是否生效:
-
SELECT sequence_name, cache_size, order_flag FROM dba_sequences WHERE sequence_name = 'S1';——ORDER_FLAG应为N -
SELECT inst_id, last_number FROM gv$sequence WHERE sequence_name = 'S1';—— 各节点LAST_NUMBER应有明显差异
真正容易被忽略的点是:IDENTITY 列背后的隐式序列不受 Oracle 19.10+ 的 Sequence dynamic cache resizing 影响,必须显式创建带 SCALE 的序列才能在 RAC 中进一步打散写入热点。











