ADG备库必须使用NOCACHE序列,因CACHE值不写入重做日志,切换后会导致序列跳变或重复;推荐改用IDENTITY列,或确保主库创建时指定NOCACHE ORDER。

ADG备库不能直接缓存序列(NOCACHE 是必须的),否则切换后主库序列值会跳变或重复——这是最常被忽略的底层约束。
为什么 ADG 备库上 SEQUENCE 不能用 CACHE
ADG 物理备库通过重做日志块级应用同步,不解析 SQL 语义。序列的 CACHE 值只在主库内存中维护,不会写入重做流;备库重启或日志应用中断后,缓存丢失无法重建。更关键的是:一旦发生主备切换,原备库升主后若沿用旧缓存,会导致序列值回退或重复,破坏业务唯一性约束(比如订单号、单据号)。
常见错误现象:
- 应用连 ADG 查询时偶尔报
ORA-08004: sequence TEST_SEQ.NEXTVAL exceeds MAXVALUE and cannot be instantiated(其实是缓存失效后尝试重载失败) - 主库插入正常,ADG 上查到的
CURRVAL明显滞后或为NULL - 切换后新主库生成重复 ID,触发应用层唯一键冲突
替代方案:用 IDENTITY 列 + GENERATED ALWAYS AS IDENTITY
Oracle 12c+ 推荐用标识列替代序列,它天然适配 ADG:值在 DML 执行时由内核生成并写入重做,备库能完整还原。即使主库用 CACHE,备库也能正确继承当前值。
实操建议:
- 新建表优先定义
id NUMBER GENERATED ALWAYS AS IDENTITY,无需额外序列对象 - 已有表可在线添加:
ALTER TABLE t1 ADD id NUMBER GENERATED ALWAYS AS IDENTITY - 如需控制起始值/步长,加
START WITH 1000 INCREMENT BY 10 - 查询时直接
SELECT id FROM t1即可,无需NEXTVAL调用
如果必须用序列:只读场景下如何最小化性能影响
当遗留系统强依赖序列且无法改造为 IDENTITY,可在 ADG 上接受「无缓存但可控」的折中:
- 主库创建序列时明确指定
NOCACHE:CREATE SEQUENCE s1 NOCACHE ORDER(ORDER防止 RAC 环境乱序) - 避免在 ADG 上执行
NEXTVAL—— 只读模式下该操作会报ORA-16000: database open for read-only access - 若应用确需从 ADG 获取序列值(如报表取号),改用主库专用连接池,或通过 DBLINK 从主库取值(注意网络延迟和事务边界)
- 监控序列使用频率:
SELECT * FROM v$segment_statistics WHERE object_name = 'S1' AND statistic_name = 'logical reads',高频访问说明设计有误
真正容易被忽略的点是:很多人试图在 ADG 上 ALTER SEQUENCE ... CACHE 20,这命令虽能执行成功,但实际不生效——备库的序列对象始终处于只读状态,所有 DDL 修改都会被忽略,且无任何告警。


















