RAC中SEQUENCE性能瓶颈源于ORDER模式强制跨节点同步,即使CACHE也需DFS锁协调;解决关键是NOORDER+合理CACHE(50–500),避免全局锁争用。
为什么 RAC 中 SEQUENCE 会成为性能瓶颈
在 oracle rac 环境下,普通 sequence(尤其带 cache 但没加 noorder)容易引发跨节点的全局锁争用。根本原因是:即使启用了 cache,oracle 仍需在序列号耗尽时通过 seq$ 表和 dfs lock 协调各实例的 nextval 分配,而默认的 order 属性强制要求严格递增顺序,导致每次 cache 切换都触发跨节点同步。
-
ORDER模式下,哪怕只用CACHE 100,当实例 A 用完第 1–100,要取 101,就得跟实例 B 确认“你没用过 101”,这个确认走的是高开销的全局队列(如SVS或DFS) - RAC 节点越多,争用越明显;
v$enqueue_stat里常看到SQ(Sequence Enqueue)或SVS等待事件飙升 - 现象通常是应用侧
SELECT seq_name.NEXTVAL FROM DUAL响应时间毛刺明显,且集中在某些时间段(比如批量导入启动时)
CACHE 值设多大才安全又高效
CACHE 不是越大越好,也不是越小越稳——它本质是在「减少物理读」和「降低内存/重启丢失量」之间做权衡。RAC 下还要叠加节点间分配粒度的问题。
- 典型误操作:
CACHE 10000+ORDER→ 一个实例独占 1w 号段,其他实例等它用完才能抢下一段,反而放大单点压力 - 推荐值范围:50–500,具体看业务并发量和单次批量插入规模;例如每秒 200 条 insert,每批 50 条,
CACHE 200可支撑 1 秒内无跨节点协调 - 注意:
CACHE值写进数据字典后,重启实例会丢失未用完的号段(比如CACHE 100,已用 85,剩 15,实例宕机后这 15 就跳过了),这不是 bug,是设计行为
必须搭配 NOORDER,否则 CACHE 几乎白设
NOORDER 是 RAC 下解锁 SEQUENCE 性能的关键开关。它放弃跨实例的严格递增保证,允许每个实例独立维护自己的 cache 号段,彻底消除 ORDER 引发的全局协调开销。
- 不加
NOORDER的CACHE序列,在 RAC 中实际仍是“伪缓存”——cache 只缓解本地查询,不缓解跨节点同步 - 加了
NOORDER后,v$lock和v$enqueue_stat中SQ类等待几乎归零,gv$sequence显示各实例的LAST_NUMBER差距可能达几百上千(正常) - 副作用:生成的值不再全局有序(比如实例1出 101–200,实例2同时出 201–300,但网络延迟可能导致 201 先入库),如果业务依赖严格递增(如审计流水号排序),就不能用
创建高性能 RAC 序列的最小安全模板
不要直接改已有序列(ALTER SEQUENCE ... CACHE 不影响 ORDER/NOORDER 属性),新建时一步到位。
CREATE SEQUENCE seq_order_id START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 999999999999999999999999999 NOCYCLE CACHE 200 NOORDER;
-
NOORDER必须显式写出,不能省略(默认是ORDER) -
CACHE值建议从 200 起调,上线后观察gv$sequence.CACHE_SIZE和LAST_NUMBER变化节奏,再微调 - 避免用
NOMAXVALUE(隐式转成极大数),有些老版本 RAC 对它处理异常;显式写MAXVALUE更稳 - 如果业务真需要全局有序,别硬扛——考虑用
IDENTITY列(12c+)、DBMS_SCHEDULER定时补位,或应用层分布式 ID(如雪花算法)
真正难的不是语法,是判断业务能否接受非严格有序。很多人卡在这一步,反复调 CACHE 却不碰 NOORDER,等于在锁住的门上擦门把手。











