Oracle 19c RAC中enq: SQ-contention主因是Sequence的CACHE过小且未设NOORDER;CACHE=20时多实例快速耗尽号段,触发频繁DFS锁争用,ORDER更恶化性能;应查GV$_SEQUENCES定位低CACHE高ORDER序列并改CACHE≥1000且加NOORDER。
oracle 19c 中出现大量 enq: sq - contention,基本就是 sequence 的 cache 太小,且没配 noorder —— 不是 sql 写得有问题,也不是硬件扛不住,就是序列参数没调对。
为什么 CACHE=20 在 RAC 下会崩
Oracle 默认建 Sequence 时设 CACHE 20,意味着每个实例最多缓存 20 个号;RAC 多节点并发一上来,这 20 个号几毫秒就用光。下一次 NEXTVAL 必须抢着去更新数据字典表 seq$、申请 DFS 锁、同步跨节点状态——所有这些动作都卡在同一个锁上,enq: SQ - contention 就爆了。
-
CACHE越小,号段耗尽越快,争用越密集 - RAC 下
ORDER会让问题雪上加霜:它强制全局有序,每次取值都要跨节点协调,本质是用性能换连续性 -
NOORDER是 RAC 必选项(除非业务真要求严格递增)
怎么查哪些 Sequence 在拖后腿
别猜,直接查 GV$_SEQUENCES(RAC 必用视图,单机可用 DBA_SEQUENCES):
SELECT SEQUENCE_OWNER, SEQUENCE_NAME, CACHE_SIZE, ORDER_FLAG FROM GV$_SEQUENCES WHERE CACHE_SIZE < 100;
重点关注 CACHE_SIZE < 100 且 ORDER_FLAG = 'Y' 的序列。另外,如果发现 SYS.AUDSESS 或 SYS.AUDSED$ 也在列表里,说明登录风暴正在发生——这个系统序列默认 CACHE 20,高并发短连接时极易中招。
改 CACHE 和 NOORDER 的实操要点
改法很简单,但有三个硬约束必须守住:
- 必须用
ALTER SEQUENCE ... CACHE N NOORDER,不能只改CACHE留着ORDER—— 那等于没改 -
N建议从1000起步;若序列每秒被调用超 50 次,可试5000;避免设成 100 的整数倍(如 200、500),减少“号段集体耗尽”概率 - 修改后无需重启实例,但旧会话里已缓存的号段仍按原
CACHE生效,新会话立即生效
示例:
ALTER SEQUENCE SQ_MENULOG CACHE 1000 NOORDER; ALTER SEQUENCE SQ_PUBLOGS CACHE 1000 NOORDER;
还有哪些坑容易被忽略
最常被跳过的其实是“谁在用这个 Sequence”。一个 enq: SQ - contention 等待事件的 P2 值就是 Sequence 的 OBJECT_ID,结合 DBA_OBJECTS 能准确定位到具体对象;但更关键的是,要顺藤摸瓜找到调用它的 SQL 或 PL/SQL —— 比如 p_pub_user_online_curd 这类高频存储过程,可能每秒调用几十次 NEXTVAL,这时光调大 CACHE 只是缓解,还得看应用层是否能批量预取、或改用应用级 ID 生成。


















