假设必须在灾难后恢复 Oracle 实例。序列是否会重置为初始状态或上次保存的状态,或者是否保留了缓存值?
非常感谢你。:-)
序列值存储在 SYSTEM.SEQ$ (我认为)表中,并且在内存中维护要使用的下一个值的缓存,该缓存的大小取决于序列的 CACHE 值。
当缓存耗尽时,SEQ$ 表被更新为一个新值(以一种不一致的方式——即,没有应用用户会话的事务控制),接下来从内存中读取 100 个值(如果 CACHE=100) .
假设您正在使用缓存大小为 20 的序列。当您从序列中选择某个值(例如 1400)时,SEQ$ 表会更新为值 1420。即使您回滚事务,SEQ$在使用下一个 20 个序列值之前仍然具有该值,此时 SEQ$ 被更新为 1440。如果您刚刚使用了值 1423 并且发生了实例崩溃,那么当系统重新启动要从中读取的下一个值序列将是 1440。
所以,是的,序列的完整性将被保留,并且不会“重新发布”号码。请注意,这同样适用于正常关闭——当您重新启动时,您将在上面的示例中获得一个新值 1440。由于这个原因,序列在实践中不能保证没有间隙(也因为使用一个值然后回滚不会将该值恢复到缓存中)。
并不是说我对此有任何经验,但我非常假设恢复到一致的系统更改编号状态也会将序列返回到最后保存的状态。就恢复而言,其他任何事情都将毫无用处。
至于缓存的值,即使实例以有序的方式关闭(*),这些值也会(可能)丢失:实例将多个序列值缓存在内存(SGA)中,而不是每次都进入数据库。实例保留的未使用序列值可能会“消失”,从而在序列中留下空白。
(*) 8i 文档提到这可能发生在并行实例 (RAC) 中,在这种情况下,序列甚至可能不是严格递增的(但仍然是唯一的),10g 文档说它发生在实例失败的情况下。