分享ORACLE SEQUENCE跳号总结

发布时间 - 2026-01-11 03:03:48    点击率:

在ORACLE数据库中,序列(SEQUENCE)是使用非常频繁的一个数据库对象,但是有时候会遇到序列(SEQUECNE)跳号(skip sequence numbers)的情形,那么在哪些情形下会遇到跳号呢? 

事务回滚引起的跳号 

不管序列有没有CACHE、事务回滚这种情况下,都会引起序列的跳号。如下实验所示: 

SQL> create sequence my_sequence
 2 start with 1
 3 increment by 1
 4 maxvalue 99999
 5 nocache;
Sequence created.
SQL> create table test(id number(10), name varchar2(32));
Table created.
SQL> insert into test
 2 select my_sequence.nextval , 'kerry' from dual;
1 row created.
SQL> 
SQL> rollback;
Rollback complete.
SQL> select my_sequence.nextval from dual;
 NEXTVAL
----------
  3
SQL>

并发访问序列引起的跳号 

并发访问序列引起的跳号,其实不算真正的跳号,而只是逻辑跳号,只是序列值被其它并发会话使用了。我们来构造一起并发访问序列引起的跳号,我们开启两个会话窗口,循环获取序列的值,模拟并发出现的场景。 

会话窗口A: 

exec dbms_lock.sleep(2); --延迟2秒执行,根据你实验情况调整
/
begin
 for i in 1 .. 2000 loop
 dbms_output.put_line(my_sequence.nextval);
 end loop;
end;
/

会话窗口B: 

spool test.txt;
begin
 waitfor delay '00:00:10';
 for i in 1 .. 2000 loop
 dbms_output.put_line(my_sequence.nextval);
 end loop;
end;
/
spool off; 

 如下所示,我构造的实验当中,你会看到序列的跳号情况。

FLUSH SHARED_POOL会导致CACHE的序列跳号 

实验测试如下所示(序列的CACHE值必须大于0),当然正常情况下,很难遇到这种情况。 

SQL> select test.my_sequence.nextval from dual;
 NEXTVAL
----------
 17004
SQL> alter sequence test.my_sequence cache 40;
Sequence altered.
SQL> select test.my_sequence.nextval from dual;
 NEXTVAL
----------
 17005
SQL> alter system flush share_pool;
alter system flush share_pool
*
ERROR at line 1:
ORA-02000: missing SHARED_POOL/BUFFER_CACHE/GLOBAL CONTEXT keyword
SQL> alter system flush shared_pool;
System altered.
SQL> select test.my_sequence.nextval from dual;
 NEXTVAL
----------
 17045

数据库实例异常关闭导致跳号

如下实验所示,当数据库使用shutdown abort命令关闭后,重新启动实例,序列缓存在shared pool里面没有用过的值都没有了。一下子从17045跳到17085 

SQL> select test.my_sequence.currval from dual;
 CURRVAL
----------
 17045
SQL> select object_id from dba_objects where object_name=upper('my_sequence');
 OBJECT_ID
----------
 97760
SQL> select increment$, minvalue, maxvalue,highwater, cache
 2 from seq$ where obj#=97760;
INCREMENT$ MINVALUE MAXVALUE HIGHWATER CACHE
---------- ---------- ---------- ---------- ----------
  1  1 99999 17085  40
SQL> shutdown abort;
ORACLE instance shut down.
SQL> startup;
ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance
ORACLE instance started.
Total System Global Area 1620115456 bytes
Fixed Size   2213816 bytes
Variable Size  1258293320 bytes
Database Buffers  352321536 bytes
Redo Buffers  7286784 bytes
Database mounted.
Database opened.
SQL> select test.my_sequence.currval from dual;
select test.my_sequence.currval from dual
  *
ERROR at line 1:
ORA-08002: sequence MY_SEQUENCE.CURRVAL is not yet defined in this session
SQL> select test.my_sequence.nextval from dual;
 NEXTVAL
----------
 17085
SQL> 

另外,我们也来看看正常关闭数据库的情况下,序列会不会出现跳号,我们采用10046跟踪事件,看看正常数据库关闭情况下,会对序列做一些啥操作 

SQL> select test.my_sequence.nextval from dual;
 NEXTVAL
----------
 17085
SQL> alter session set events '10046 trace name context forever, level 4';
Session altered.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance
ORACLE instance started.
Total System Global Area 1620115456 bytes
Fixed Size   2213816 bytes
Variable Size  1258293320 bytes
Database Buffers  352321536 bytes
Redo Buffers  7286784 bytes
Database mounted.
Database opened.
SQL> select test.my_sequence.currval from dual;
select test.my_sequence.currval from dual
  *
ERROR at line 1:
ORA-08002: sequence MY_SEQUENCE.CURRVAL is not yet defined in this session
SQL> select test.my_sequence.nextval from dual;
 NEXTVAL
----------
 17086
SQL> 

Trace文件中有更新seq$数据字典表,如果你看过我这篇文章ORACLE中seq$表更新频繁的分析,基本上就知道其实seq$中维护的是序列的一些信息。通过跟踪文件,我们知道在数据库正常关闭的情况下,会触发一个update seq$的操作,把当前的sequence.nextval的值更新到seq$.highwater中,从而使得sequence在有cache的情况下,数据库正常关闭未出现nextval跳跃(currval也同样不跳跃);而在数据库异常关闭之时,数据库不能及时将sequence.nextval更新到eq$.highwater从而引起sequence cache中的值丢失,从而可能出现了sequence使用cache导致跳跃的情况 

=====================
PARSING IN CURSOR #25 len=129 dep=1 uid=0 oct=6 lid=0 tim=1504236336294194 hv=2635489469 ad='bf780410' sqlid='4m7m0t6fjcs5x'
update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,cache=:7,highwater=:8,audit$=:9,flags=:10 where obj#=:1
END OF STMT
PARSE #25:c=0,e=21,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=1935744642,tim=1504236336294194
BINDS #25:
 Bind#0
 oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
 oacflg=18 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=bf45ca48 bln=24 avl=02 flg=09
 value=1
 Bind#1
 oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
 oacflg=18 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=bf45ca5a bln=24 avl=02 flg=09
:/17086                     
 Bind#3
 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
 oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=2b7d80f57350 bln=24 avl=01 flg=05
 value=0
 Bind#4
 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
 oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=2b7d80f57320 bln=24 avl=01 flg=05
 value=0
 Bind#5
 oacdty=02 mxl=22(02) mxlc=00 mal=00 scl=00 pre=00
 oacflg=18 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=bf47b85e bln=24 avl=02 flg=09
 value=40
 Bind#6
 oacdty=02 mxl=22(04) mxlc=00 mal=00 scl=00 pre=00
 oacflg=18 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=bf47b870 bln=24 avl=04 flg=09
 value=17086
 Bind#7
 oacdty=01 mxl=32(32) mxlc=00 mal=00 scl=00 pre=00
 oacflg=18 fl2=0001 frm=01 csi=873 siz=32 off=0
 kxsbbbfp=bf47b882 bln=32 avl=32 flg=09
 value="--------------------------------"
 Bind#8
 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
 oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=2b7d80f572f0 bln=24 avl=02 flg=05
 value=8
 Bind#9
 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
 oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
 kxsbbbfp=2b7d80f57380 bln=22 avl=04 flg=05
 value=97760
EXEC #9:c=999,e=709,p=0,cr=1,cu=2,mis=0,r=1,dep=1,og=4,plh=1935744642,tim=1504236336297033
CLOSE #9:c=0,e=2,dep=1,type=3,tim=1504236336297058
mealink上提到了使用dbms_shared_pool.keep将对象在锁定在shared pool 中,永远不释放。这样可以防止FLUSH SHARED POOL导致序列跳号,但是这个无法避免数据库异常关闭或CRASH引起的跳号
SQL> select test.my_sequence.currval from dual;
 CURRVAL
----------
 17086
SQL> exec dbms_shared_pool.keep('test.my_sequence','q');
PL/SQL procedure successfully completed.
SQL> alter system flush shared_pool;
System altered.
SQL> select test.my_sequence.currval from dual;
 CURRVAL
----------
 17086
SQL> shutdown abort
ORACLE instance shut down.
SQL> startup
ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance
ORACLE instance started.
Total System Global Area 1620115456 bytes
Fixed Size   2213816 bytes
Variable Size  1258293320 bytes
Database Buffers  352321536 bytes
Redo Buffers  7286784 bytes
Database mounted.
Database opened.
SQL> select test.my_sequence.nextval from dual;
 NEXTVAL
----------
 17126

其实如果业务允许,单号出现跳号也无所谓的情形最好,如果碰到业务要求绝对不能出现单号出现跳号的情况,那么就不能使用序列号了,就必须使用其它替代方案,此处不做展开说明!

总结

以上所述是小编给大家介绍的分享ORACLE SEQUENCE跳号总结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# oracle  # sequence  # 跳号  # 通过实例了解Oracle序列Sequence使用方法  # Oracle中使用触发器(trigger)和序列(sequence)模拟实现自增列实例  # 详解ORACLE SEQUENCE用法  # oracle sequence语句重置方介绍  # oracle重置序列从0开始递增1  # oracle中创建序列及序列补零实例详解  # ORACLE实现自定义序列号生成的方法  # oracle 重置序列从指定数字开始的方法详解  # Oracle中的序列SEQUENCE详解  # 情况下  # 所示  # 小编  # 新到  # 的是  # 如果你  # 很难  # 你会  # 在此  # 中有  # 会不会  # 我这  # 而在  # 之时  # 给大家  # 会对  # 这种情况  # 就不能  # 不做  # 用过 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  香港服务器网站卡顿?如何解决网络延迟与负载问题?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  EditPlus 正则表达式 实战(3)  如何挑选最适合建站的高性能VPS主机?  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  javascript如何操作浏览器历史记录_怎样实现无刷新导航  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  IOS倒计时设置UIButton标题title的抖动问题  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  Laravel如何使用查询构建器?(Query Builder高级用法)  如何快速搭建高效服务器建站系统?  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  如何在阿里云服务器自主搭建网站?  Laravel如何生成URL和重定向?(路由助手函数)  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  Laravel怎么上传文件_Laravel图片上传及存储配置  Python进程池调度策略_任务分发说明【指导】  详解Android中Activity的四大启动模式实验简述  Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】  如何在香港免费服务器上快速搭建网站?  济南网站建设制作公司,室内设计网站一般都有哪些功能?  canvas 画布在主流浏览器中的尺寸限制详细介绍  如何在云指建站中生成FTP站点?  如何用美橙互联一键搭建多站合一网站?  Thinkphp 中 distinct 的用法解析  如何在阿里云香港服务器快速搭建网站?  Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧  使用spring连接及操作mongodb3.0实例  Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控  JS弹性运动实现方法分析  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  Python文本处理实践_日志清洗解析【指导】  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  如何确保FTP站点访问权限与数据传输安全?  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  如何快速搭建高效简练网站?  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  Python正则表达式进阶教程_复杂匹配与分组替换解析  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  网站图片在线制作软件,怎么在图片上做链接?  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  香港服务器如何优化才能显著提升网站加载速度?