SEQUENCE#跳号源于主库CACHE/NOORDER配置与内存机制,DG仅重放不干预;归档日志SEQUENCE#断号才表示日志Gap,二者无关。
sequence# 跳号不是 dg 环境“导致”的,而是主库序列(sequence)配置与 oracle 内存管理机制共同作用的结果。dg 本身不生成、不修改、不干预序列值,它只重放主库已提交的 nextval 操作——跳号现象完全源于主库侧。
SEQUENCE 的 CACHE 和 NOORDER 是关键
-
CACHE值越小,跳号越频繁:比如CACHE=20,每次从共享池取 20 个号预分配;若实例异常重启或该序列对象被 LRU 清出共享池(shared pool),未用完的号就永久丢失,下次取时直接从“上一批末尾+1”开始。 -
ORDER在 RAC 环境下强制所有实例的NEXTVAL请求路由到同一节点,引发 DFS 锁争用;而 ADG 备库的 MRP 进程是单线程串行重放,会把主库的锁等待放大为日志应用延迟,间接加剧“看起来跳得更猛”的错觉。 -
NOORDER不保证严格连续,但能消除 RAC 单点瓶颈;配合足够大的CACHE(如CACHE=1000),可大幅降低跳号概率。
主库序列跳号在 DG 中“可见”,但备库无法修复或干预
- 备库是物理只读,执行
ALTER SEQUENCE或CREATE SEQUENCE直接报ORA-16000。 -
CURRVAL是会话级变量,备库无会话上下文,根本不维护;所谓“主备序列值不一致”是误解——NEXTVAL值由主库生成并固化在归档日志中,重放即确定。 - 有人试图用
DBMS_SHARED_POOL.KEEP固定序列进共享池来防跳号,但需注意:DBMS_SHARED_POOL包默认不存在,必须由SYS执行@$ORACLE_HOME/rdbms/admin/dbmspool.sql安装,且仅对单实例有效;RAC 下各节点仍需分别KEEP,运维成本高,不如直接调大CACHE+NOORDER。
真正要盯住的是 V$ARCHIVED_LOG.SEQUENCE# 是否连续
- 这个
SEQUENCE#是归档日志文件自身的编号,和用户序列(SEQUENCE对象)无关。 - 如果这里出现断号(如 1001、1002、1004),说明归档日志缺失,属于
Gap问题,需查V$ARCHIVE_GAP、检查LOG_ARCHIVE_DEST_STATE_2是否启用、网络是否通、FRA 是否满(ORA-00257)。 - 别把两类
SEQUENCE#混为一谈:一个管日志文件流水号,一个管业务主键生成——它们底层毫无关系,只是名字撞了。
跳号本身不影响数据一致性,但暴露了主库序列设计的脆弱性;尤其在高并发 RAC+ADG 场景下,ORDER + 小 CACHE 是典型的性能反模式。


















