这是正常的。根据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个值,或者其他影响它的事件发生(例如数据库被重置、序列再次被改变等),数据字典中的内容将不会再改变。