2008-12-17 50 views

回答

7

存储值存储在SYSTEM.SEQ $(我认为)表中,缓存保存在下一个要使用的值的内存中,该缓存的大小取决于CACHE值序列。

当缓存耗尽时,SEQ $表被更新为新值(以不一致的方式 - 即没有用户会话的Transacton控制应用),接下来说100个值(如果CACHE = 100)从内存中读取。

假设您正在使用缓存大小为20的序列。当您从序列中选择某个值(比如说1400)时,SEQ $表会更新为值1420.即使您回滚了事务中,SEQ $仍然具有该值,直到使用了接下来的20个序列值,此时SEQ $被更新为1440.如果您刚刚使用了值1423并发生实例崩溃,那么当系统重新启动下一个值从后续读取将是1440.

所以,是的序列完整性将被保留,数字将不会被“重新发布”。请注意,这同样适用于正常关机 - 当您重新启动时,您将在上面的示例中获得1440的新值。由于这个原因,序列在实践中不保证没有间隙(也是因为使用一个值然后回滚不会将该值恢复到缓存)。

2

不是我对此有任何经验,但我非常认为恢复到一致的系统更改编号状态也会将序列返回到上次保存的状态。在恢复方面,其他任何东西都是毫无用处的。

对于缓存值,即使实例以有序方式关闭(*),它们也(可能)丢失:实例将大量序列值缓存到内存(SGA)中,而不是每次都去数据库。实例已保留的未使用的序列值可能“消失”,从而在序列中留下缺口。 (*)8i文档提到这可能发生在并行实例(RAC)中,在这种情况下,序列甚至可能不是严格递增的(但仍然是唯一的),10g文档说它发生在实例故障的情况下。