这是正常的,是的。来自documentation for the all_sequences data dictionary view,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
last_number被缓存大小跳了起来,这是正常的。
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时多十个值。
保存到磁盘的值大部分在那里,因此如果数据库崩溃,它知道从哪里获取。重新启动时,序列将从记录的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 个值,或者其他地方发生了影响它 - 数据库被退回,序列再次被改变,等等。