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

时间:2016-01-24 12:07:10

标签: sql oracle oracle11g 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

  

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

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

1 个答案:

答案 0 :(得分: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!