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

Luk*_*der 3 sql oracle sequence oracle11g

请考虑以下代码:

create sequence "s" cache 50;
select "s".nextval from dual;
Run Code Online (Sandbox Code Playgroud)

当我执行上述一次时,我得到了

NEXTVAL
-------
1
Run Code Online (Sandbox Code Playgroud)

当我执行两次语句时,除了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
Run Code Online (Sandbox Code Playgroud)

运行语句三次以获得:

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
Run Code Online (Sandbox Code Playgroud)

文件写道:

如果发生系统故障,则所有未在已提交的DML语句中使用的高速缓存序列值都将丢失.

但是,失败的DDL语句是否有资格成为系统故障?这种行为的原因是什么?

Inc*_*ito 6

当我们第一次执行DDL(CREATE SEQUENCE SEQ1 CACHE 50)时,会输入一个条目v$DB_OBJECT_CACHE.

在您获取序列值之前,您会注意到shareable_mem列没有条目存储对象使用的共享池中的可共享内存量.一旦获取序列的下一个值(第一次),您就会注意到该shareable_mem列有一个值(Oracle在共享池中分配内存).

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

这种(重置shareable_mem)行为也与其他DDL一致.我创建了一个表,注意到V $ _DB_OBJECT_CACHE中的一个条目,其值为shareable_mem.一旦我执行相同的DDL shareable_mem值就重置为0!