Oracle RAC中SCN同步非实时,依赖Lamport算法或Broadcast-on-Commit机制;默认Lamport模式下存在最高7秒延迟,可能导致读一致性场景下查询结果非最新,属正常行为而非逻辑异常。
oracle rac 中不同节点的 scn 同步本身不会导致“逻辑异常”,但若应用依赖强实时读一致性,而 scn 传播存在延迟,就可能观察到看似矛盾的查询结果——这不是数据库出错,而是读一致性机制在分布式环境下的正常表现。
默认情况下,RAC 并不保证每个 COMMIT 后所有实例立刻看到相同 SCN。它依赖两种机制之一:
MAX_COMMIT_PROPAGATION_DELAY ≥ 100 厘秒):靠消息携带 SCN + 定期心跳对齐,空闲时快、高负载时可能接近上限延迟(如 7 秒)MAX_COMMIT_PROPAGATION_DELAY = 0 或 关键点在于:Lamport 模式下,B 实例在 A 提交后的一段时间内,仍可能用旧 SCN 构造一致性读视图,从而查不到刚提交的数据——这不是数据丢失,是 Oracle 故意为之的可重复读保障。
MAX_COMMIT_PROPAGATION_DELAY=0 不一定解决问题设为 0 确实启用 Broadcast-on-Commit,但实际效果受制于底层通信和负载:
log file sync 等待时间上升MAX_COMMIT_PROPAGATION_DELAY 是全局参数,所有实例必须设为相同值;若漏改某个实例,该节点将按旧值运行,造成不一致行为此时你可能看到部分节点 SCN 跳变滞后,v$database 的 CURRENT_SCN 在各节点间短暂差异超过几百甚至上千——只要没超 _scn_rate_limit 限制,Oracle 认为合法。
典型表现是跨实例查询结果不一致,常见于以下使用方式:
SELECT ... AS OF SCN = xxx 时,xxx 来自实例 A 的 CURRENT_SCN,但在实例 B 上该 SCN 尚未生效,报 ORA-01466
这类问题不会触发 ORA 错误,也不会破坏事务原子性,但会打破应用预期的“提交即可见”假设。
别只看 v$database.CURRENT_SCN,它反映的是本地 SGA 中缓存的 SCN,未必已广播完成:
v$instance 的 SCN 列(Oracle 12c+),比 v$database 更贴近 LGWR 实际推进进度SELECT dbms_flashback.get_system_change_number FROM dual,该函数强制触发一次 SCN 获取,更接近真实值GV$SYSSTAT 中 global cache cr blocks served 和 global cache current blocks served,突增说明 GC 流量正推动 SCN 对齐真正难处理的不是 SCN 差值本身,而是应用层没有适配 RAC 的分布式时序模型——把 RAC 当单机用,最容易掉进这个坑。