我有序列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_NUMBER
已从2222292456
更改为2222292447
。
这是因为改变脚本而发生的吗?
答案 0 :(得分:14)
这是正常的,是的。从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个值,或其他影响它的事情 - 数据库被反弹,序列再次被改变等等。
答案 1 :(得分:6)
当序列在缓存中时,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>