我有一个序列SEQ_PAGE_ID
SEQUENCE_NAME INCREMENT_BY CACHE_SIZE LAST_NUMBER
-------------------------------------------------------
SEQ_PAGE_ID 1 20 2222292456
Run Code Online (Sandbox Code Playgroud)
要更改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
Run Code Online (Sandbox Code Playgroud)
从LAST_NUMBER改变2222292456为2222292447.这是因为更改脚本而发生的吗?
Ale*_*ole 15
这是正常的,是的.从数据字典视图的文档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
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
在last_number下降,但是现在反映实际产生的最后一个序列号.DDL(显然)导致写入磁盘的数据被更新以反映当前值,而不是缓存的顶部 - 旧的20值缓存或新的5000值缓存.在你的情况下,你得到了2222292447,这意味着你通过缓存的十个值比我运行时的值要多alter.
保存到磁盘的值很大,因此如果数据库崩溃,它知道从哪里拿起.重新启动时,序列将开始从记录中生成数字last_number.在正常运行期间,它不需要再引用它,它只是在缓存新值时更新磁盘上的值.这可以防止序列号在崩溃后重新发布,而无需进行昂贵的(慢速)锁定来实时维护该值 - 毕竟这是缓存所要避免的.
如果last_value低于实际生成的序列,则只会出现问题,但这种情况不会发生.(好吧,除非序列设置为循环).
SQL> select SEQ_PAGE_ID.nextval from dual;
NEXTVAL
----------
2222292437
Run Code Online (Sandbox Code Playgroud)
生成的下一个序列号从高速缓存大小更改之前的最后一个序列号开始; 它没有重用旧值,因为你可能一直担心字典值.
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
Run Code Online (Sandbox Code Playgroud)
在last_number现在显示通过的5000什么是数据字典,现在不会再改变缓存大小递增上次存储的值,直到我们已经消耗了所有5000个值形成的高速缓存,或有事别处影响它-数据库是弹跳,序列再次被改变,等等
当序列在缓存中时,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>
Run Code Online (Sandbox Code Playgroud)