Oracle序列中的LAST_NUMBER是什么意思?

13

我有一个序列SEQ_PAGE_ID

SEQUENCE_NAME   INCREMENT_BY  CACHE_SIZE   LAST_NUMBER            
-------------------------------------------------------
SEQ_PAGE_ID      1              20          2222292456 

为了改变CACHE_SIZE,我使用了以下脚本:

alter sequence SEQ_PAGE_ID CACHE 5000;

当我检查了查询时,

select ... from user_sequences where sequence_name  = 'SEQ_PAGE_ID';


SEQUENCE_NAME   INCREMENT_BY  CACHE_SIZE    LAST_NUMBER            
-------------------------------------------------------
SEQ_PAGE_ID      1              5000          2222292447 

LAST_NUMBER2222292456 变为 2222292447。 这是由于修改脚本引起的吗?


2
如果有人来到这里寻找LAST_NUMBER是什么,可以在这里找到 https://international-dba.blogspot.com/2012/07/lastnumber-column-in-dbasequences.html - lupchiazoem
3个回答

22

这是正常的。根据all_sequences数据字典视图的文档,last_number是:

写入磁盘的最后序列号。如果序列使用缓存,写入磁盘的数字是放置在序列缓存中的最后一个数字。该数字可能大于最后使用的序列号。

可以通过创建新序列来重新创建此内容:

SQL> create sequence SEQ_PAGE_ID start with 2222292436 increment by 1 cache 20;

sequence SEQ_PAGE_ID created.

SQL> select sequence_name, increment_by, cache_size, last_number
  2  from user_sequences where sequence_name = 'SEQ_PAGE_ID';

SEQUENCE_NAME                  INCREMENT_BY CACHE_SIZE LAST_NUMBER
------------------------------ ------------ ---------- -----------
SEQ_PAGE_ID                               1         20  2222292436 

SQL> select SEQ_PAGE_ID.nextval from dual;

   NEXTVAL
----------
2222292436 

SQL> select sequence_name, increment_by, cache_size, last_number
  2  from user_sequences where sequence_name = 'SEQ_PAGE_ID';

SEQUENCE_NAME                  INCREMENT_BY CACHE_SIZE LAST_NUMBER
------------------------------ ------------ ---------- -----------
SEQ_PAGE_ID                               1         20  2222292456 

最后一个数字上升了缓存大小,这是正常的。

SQL> alter sequence SEQ_PAGE_ID CACHE 5000;

sequence SEQ_PAGE_ID altered.

SQL> select sequence_name, increment_by, cache_size, last_number
  2  from user_sequences where sequence_name = 'SEQ_PAGE_ID';

SEQUENCE_NAME                  INCREMENT_BY CACHE_SIZE LAST_NUMBER
------------------------------ ------------ ---------- -----------
SEQ_PAGE_ID                               1       5000  2222292437 

last_number下降,但现在反映的是实际生成的最后序列号。DDL(似乎)导致写入磁盘的数据被更新为反映当前值,而不是缓存顶部-旧的20值缓存或新的5000值缓存。在您的情况下,您得到了2222292447,这意味着当我运行alter时,您比我多使用了10个缓存值。

保存到磁盘的值主要是为了在数据库崩溃时知道从哪里开始继续。重新启动后,序列将从记录的last_number开始生成数字。在正常运行期间,它不需要参考那个值,只需在缓存新值时更新磁盘上的值。这样可以避免在维护实时值时执行昂贵(慢速)的锁定,而缓存的目的就是为此而存在。

仅当last_value小于实际生成的序列时才会出现问题,但这是不可能的。(除非序列被设置为循环)。

SQL> select SEQ_PAGE_ID.nextval from dual;

   NEXTVAL
----------
2222292437 

生成的下一个序列号是在缓存大小更改之前的最后一个序列号之后; 它并没有重用旧的值,这可能是您从字典值中担心的。

SQL> select sequence_name, increment_by, cache_size, last_number
  2  from user_sequences where sequence_name = 'SEQ_PAGE_ID';

SEQUENCE_NAME                  INCREMENT_BY CACHE_SIZE LAST_NUMBER
------------------------------ ------------ ---------- -----------
SEQ_PAGE_ID                               1       5000  2222297437 

last_number现在显示的是之前存储的值加上缓存大小5000。直到我们消耗完缓存中的5000个值,或者其他影响它的事件发生(例如数据库被重置、序列再次被改变等),数据字典中的内容将不会再改变。


7

当序列在缓存中时,last_number代表Oracle保存的数字。当不在缓存中时,它代表Oracle使用的最后一个序列号。通过您的alter命令,您可以更改序列的设置,因此Oracle会刷新其“序列缓存”。

这里是一个简单的例子:

SQL> drop sequence test;
Sequence dropped

SQL> create sequence test cache 20;
Sequence created

SQL> select last_number  from user_sequences where sequence_name='TEST';
LAST_NUMBER
-----------
          1

SQL> select test.nextval from dual;
   NEXTVAL
----------
         1

SQL>  select last_number  from user_sequences where sequence_name='TEST';
LAST_NUMBER
-----------
         21

SQL> alter sequence test CACHE 5000;
Sequence altered

SQL>  select last_number  from user_sequences where sequence_name='TEST';
LAST_NUMBER
-----------
          2

SQL> select test.nextval from dual;
   NEXTVAL
----------
         2

SQL>  select last_number  from user_sequences where sequence_name='TEST';
LAST_NUMBER
-----------
       5002

SQL> 

0

本贴是关于更改最后一个数字的内容 :)

假设在序列xyz中,LAST_NUMBER为3953,您想将其更改为205233,则需要将序列增加(205233 - 3953 = 201,280),然后再增加1。可以通过以下语句实现:

要更改LAST_NUMBER为

ALTER SEQUENCE xyz INCREMENT BY 201280;
SELECT xyz.nextval from dual;
ALTER SEQUENCE xyz INCREMENT BY 1;

现在,LAST_NUMBER将被更新为205233

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接