为什么 Oracle 的序列在尝试重新创建序列时会跳过它们的缓存值?

Why do Oracle's sequences skip their cached values when attempting to re-create the sequence?

考虑以下代码:

create sequence "s" cache 50;
select "s".nextval from dual;

当我执行一次以上时,我得到

NEXTVAL
-------
1

当我执行语句两次时,除了 DDL 语句上明显的错误消息外,我得到

drop sequence "s";
create sequence "s" cache 50;
select "s".nextval from dual;
create sequence "s" cache 50;
select "s".nextval from dual;

NEXTVAL
-------
51

运行语句三次得到:

drop sequence "s";
create sequence "s" cache 50;
select "s".nextval from dual;
create sequence "s" cache 50;
select "s".nextval from dual;
create sequence "s" cache 50;
select "s".nextval from dual;

NEXTVAL
-------
101

doc reads:

If a system failure occurs, then all cached sequence values that have not been used in committed DML statements are lost.

但是失败的 DDL 语句是否属于系统故障?这种行为的原因是什么?

当我们第一次执行DDL (CREATE SEQUENCE SEQ1 CACHE 50)时,会在v$DB_OBJECT_CACHE.

中创建一个条目

直到您获取序列值时,您会注意到 shareable_mem 列没有条目,该列存储对象消耗的共享池中的可共享内存量。一旦您获取序列的下一个值(第一次),您会注意到此 shareable_mem 列有一个值(Oracle 在共享池中分配内存)。

当我们 re-execute DDL(相同的语句)时,shareable_mem 被重置为 0 - 当然会释放缓存值。同时,请记住 Oracle 已经为这个序列存储了 LAST_NUMBER(我们第一次创建序列时为 50)。由于 shareable_mem 被刷新并且缓存值消失,LAST_NUMBER 现在更新为 CURRVAL + *CACHE SIZE*

此行为(重置 shareable_mem)也与其他 DDL 一致。我创建了一个 table 并注意到 V$_DB_OBJECT_CACHE 中有一个值为 shareable_mem 的条目。一旦我执行了相同的 DDL shareable_mem 值就重置为 0!