RAC中enq:SQ-contention等待明显,根本原因是默认CACHE 20导致高频跨节点同步;CACHE过小使号段快速耗尽,触发频繁数据字典更新与DFS锁争用,而NOORDER是必要配置,ORDER会引发严重性能瓶颈。
oracle rac 中 enq: sq - contention 等待明显,根本不是序列用错了,而是默认 cache 20 noorder 在高并发下撑不住——必须调大 cache,且坚决不碰 order。
为什么RAC里SEQ争用集中在CACHE=20?
Oracle 默认创建 sequence 时设 CACHE 20,意味着每个实例最多缓存 20 个号;一旦用完,就得抢着去更新数据字典表 seq$ 并申请 DFS 锁协调。在 RAC 多节点并发场景下,这 20 个号可能几毫秒就耗尽,触发高频跨节点同步,enq: SQ - contention 直接飙升。
实测数据:RAC 双节点各取 4 万个 NEXTVAL,NOCACHE 耗时 2100 秒,CACHE 1000 仅需 55 秒——差 38 倍。
-
CACHE太小 → 频繁刷seq$+ DFS 锁争用 → 等待堆积 -
CACHE太大(如 >50000)→ 实例异常重启时丢号过多,跳号肉眼可见(比如从 100000 直跳到 150000) - 单实例库也受
CACHE影响,但无跨节点锁开销,表现没那么剧烈
NOORDER 是必须选项,别被“顺序”二字带偏
RAC 下 ORDER 不是“让序列更整齐”,而是强制所有实例按全局单调递增分发号码,代价是每次 cache 切换都得串行化到一个节点(通常是第一个启动的实例),该节点瞬间成为 enq: SQ 瓶颈。加了 ORDER 后,v$lock 里 SQ 类锁激增,gv$sequence.LAST_NUMBER 在各节点几乎一致——但这不是优化,是自废武功。
-
NOORDER允许各节点独立维护本地号段,彻底消除跨节点协调,enq: SQ等待趋近于零 -
ORDER+CACHE组合在 RAC 中性能暴跌,ORDER+NOCACHE更是灾难(DFS 锁+物理写全来一遍) - 应用若真依赖严格递增顺序(极少见),应改用应用层 ID 生成器,而非硬扛数据库机制
怎么设CACHE才既稳又快?看并发节奏,别拍脑袋
CACHE 值不是越大越好,核心是匹配业务批量节奏:要让它撑过一次典型批量操作周期,避免中途刷新。
- 每秒插入 200 行、每批 50 条 →
CACHE 200可覆盖 1 秒内全部请求,推荐起步值 - 夜间批量导入峰值每秒 5000 行 →
CACHE 5000 ~ 20000更稳妥,部分客户已用到CACHE 50000 - ALTER SEQUENCE 只能改
CACHE值,不能改ORDER/NOORDER属性,要改必须重建 - 新建 sequence 务必一步到位:
CREATE SEQUENCE seq_id START WITH 1 INCREMENT BY 1 CACHE 200 NOORDER;
跳号不是 bug,是设计权衡;堵不如疏
即使设成 NOCACHE,事务回滚导致的 NEXTVAL 丢失依然存在;而 ORDER 带来的性能惩罚远超跳号本身的影响。绝大多数业务真正需要的是唯一性与单调性,不是视觉连续。
- 展示层用
ROW_NUMBER() OVER (ORDER BY create_time)补逻辑序号,和主键物理 ID 解耦 - 导出报表加一列「业务序号」,由视图或应用计算,不依赖 sequence
- 审计 SLA 明确写清:“编号允许跳号,不视为数据异常”,省去后期扯皮
- 监控
DBA_SEQUENCES.CACHE_SIZE和实际跳号幅度,若CACHE 50却平均跳 300+,说明实例频繁重启,该查 CRS 或 OS 日志了


















