http://blog.csdn.net/agaric717/article/details/6690890

一个应用上线后发现一个使用SEQUENCE值来生成的主键经常出现断号,而且断号不是一两个,而是每次几十个几十个的跳。而一般能想到的导致这种跳号的基本就是事务ROLLBAK了导致取出的SEQUENCE没有被插入到表中去,或者就是数据库关闭或者宕掉,导致已经CACHE的SEQUENCE的值丢失,导致的跳号。而在这个场景下,这两种情况都被一一排除了。那么到底什么原因导致的SEQUENCE跳号呢?

一般为了提高从SEQUENCE取值的效率,我们都会对SEQUENCE设置CACHE,而且取值越频繁的,CACHE值设置的越大。那么这个CACHE的值是保存在SHARED POOL中的,而且这块内存是可以被其他程序共享的,也就是说SEQUENCE的CACHE是会在一定的情况下被刷出SHARED POOL的,那么就相当于已经CACHE的SEQUENCE的值就丢失了,这就是导致跳号的原因。下面我们通过一个示例来证明并展开来看看。

SQL> create sequence seq_bear cache 100;

Sequence created
首先创建一个CACHE值为100的SEQUENCE

SQL> select seq_bear.nextval from dual;

NEXTVAL
----------
1
查询SEQUENCE的值为1,再次查询的话,SEQUENCE取下一个值,为2

SQL> /

NEXTVAL
----------
2

SQL> alter system flush shared_pool;

System altered

SQL> select seq_bear.nextval from dual;

NEXTVAL
----------
101
而当我们刷新SHARED_POOL并再次查询的时候,SEQUENCE的值直接跳到了101,说明已经CACHE的值除了被使用的1和2之外,其他的98个全部丢失了。

那么我们如何避免这种情况呢?ORACLE给我们提供了把SEQUENCE KEEP到SHARED POOL中的方法,这样就保证了SEQUENCE的CACHE不会被交换出去,从而避免了这种情况的发生。来看下面的示例:
SQL> select seq_bear.nextval from dual;

NEXTVAL
----------
102
再次查询的时候,值为102
SQL> exec dbms_shared_pool.keep(name => 'SEQ_BEAR',flag => 'Q');

PL/SQL procedure successfully completed
使用DBMS_SHARED_POOL来KEEP SEQUENCE的CACHE

SQL> SELECT SEQ_BEAR.NEXTVAL FROM DUAL;

NEXTVAL
----------
103
再次查询,值为103 
SQL> ALTER SYSTEM FLUSH SHARED_POOL;

System altered

SQL> SELECT SEQ_BEAR.NEXTVAL FROM DUAL;

NEXTVAL
----------
104 
而这时当我们再次刷新SHARED POOL并从SEQUENCE取值的时候,发现SEQUENCE已经不再跳号了。

那么,如何能知道哪些SEQUENCE已经被KEEP了呢?
SQL> select KEPT from v$db_object_cache where name='SEQ_BEAR';

KEPT
----
YES
通过查询V$DB_OBJECT_CACHE可以看到对象是否已经被KEEP在SHARED POOL,同时,这个视图中还提供了其他的一些信息,比如对象被LOAD了多少次、占用多少内存空间等等信息

DBMS_SHARED_POOL不仅可以KEEP SEQUENCE的CACHE,还可以KEEP住存储过程、包、SQL等等,保证这些不会被交换出SHARED POOL。而KEEP方法使用也很简单,只需要传入要KEEP的对象的名称,如果是其他用户的,则使用USERNAME.OBJECT_NAME作为传入参数;后面一个参数表示要KEEP的对象的类型,比如是包、SEQUENCE、SQL还是其他。具体的取值可以参考ORACLE的文档,上面写的很详细。

同时,DBMS_SHARED_POOL还提供了其他几个方法:

ABORTED_REQUEST_THRESHOLD(threshold_size NUMBER):这个方法可以设定一个界限,保证如果要进入SHARED POOL的对象太大,那么可以设置一个阀值,超过这个阀值的直接报错,而不是经过LRU查找和内存交换之后发现SHARED POOL不够了再报错,可以防止超大对象过度占用SHARED POOL空间。

UNKEEP就是KEEP的反操作

SIZES (minsize NUMBER):这个是列出SHARED POOL中所有大于minsize的对象,对于查找SHARED POOL中大对象并设置合理的ABORTED_REQUEST_THRESHOLD很有用。

总结:
SEQUENCE跳号可能是事务ROLLBAK或者实例被宕过或者是SEQUENCE的CACHE被交换出去过,对于有特殊要求的SEQUENCE或者包、存储过程、触发器等等,可以使用DBMS_SHARED_POOL.KEEP方法,把他们永久保留在SHARED POOL中,从而可以实现一些特定的用途。

从SEQUENCE跳号说起的更多相关文章

  1. ORACLE SEQUENCE跳号总结

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

  2. SQL Server解惑——标识列的限制和跳号现象

      1:每个表只能创建一个标识列. 如下测试所示,如果表中有一个标识列,新增一个标识列就会遇到错误"Multiple identity columns specified for table ...

  3. javascript:查找“跳号”号码

    业务背景:航空货运系统中,“货运代理商”会定期从“航空公司”领取一定数量的纸质运单(每张纸上有一个单号),这些单号都是连续的(即:每次可以理解为领取一个“号段”),而且每张单子都要向航空公司交纳一定的 ...

  4. Sybase自增字段跳号的解决方法

    Sybase自增字段跳号原因及影响: 在Sybase数据库中如果数据库在开启的情况下,因为非正常的原因(死机.断电)而导致数据库服务进程强制结束. 那么自动增长的字段将会产生跳号的情况,再往数据表里面 ...

  5. 由merge into引起的序列跳号

    最近生产库反应出一个问题,某张表的主键ID并没有按照原计划的期望增加,而是间歇性跳号,每次跳2万多,经过研究发现是某个同步过程的merge into引起的,具体语句如下 merge into t_if ...

  6. MySQL--批量插入导致自增跳号问题

    对于批量插入数据的操作,MySQL申请自增的策略为: 在批量插入语句执行过程中,申请策略: .第一次申请自增值时,会分配1个 .在N次申请自增值时,会分配上一次(第N-1次)的2倍. 测试Demo: ...

  7. SAP QM 检验批跳号解决

    SAP QM 检验批跳号解决 在生产系统中,发现存在检验批规则或不规则跳号问题. 首先,查看事务代码SNRO编号范围对象QLOSE中BUFFER字段值,将其设置为NO BUFFER(无缓冲) 如果还存 ...

  8. merge into 导致序列跳号

    For each row merged by a MERGE statement. The reference to NEXTVAL can appear in the merge_insert_cl ...

  9. Oracle EBS FA 资产编号跳号

随机推荐

  1. PR合并回写

    ) as LGORT ,'SAPRFC' as ERNAM,out_pr.due_datetime,out_pr.so_id,out_pr.so_lineid,out_pr.sobsl from V_ ...

  2. 关于number...的精度问题

    一 当数字的精度被定为number(3,2)时, 这时他能输入的数字整数部分只能是3-2=1位, 小数位如果不够会用0补齐, 超出的四舍五入保留3位小数. SQL> insert into t_ ...

  3. 55. Jump Game (Array; Greedy)

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  4. Java获取资源文件

    比如我们有以下目录 |--project |--src |--javaapplication |--Test.java |--file1.txt |--file2.txt |--build |--ja ...

  5. VMware Ubuntu 窗口太小 未安装VMwareTools

    安装vmtools就行了:在虚拟机点击重新安装vmtools. 在虚拟机里点开挂载的,将那个压缩文件拉出document,解压 在命令行sudo运行.pl结尾的文件,一路回车就行了. 重启即可.

  6. .net为图片添加水印(转) jpg png和gif格式

    .net为图片添加水印(转) jpg png和gif格式 .net为图片添加水印(转) jpg png和gif格式,转自csdn的hyde82,现在跟大家一起来分享下: 利 用.net中System. ...

  7. MongoDB的数据类型(四)

    JSON JSON是一种简单的数据表示方式,它易于理解.易于解析.易于记忆.但从另一方面来说,因为只有null.布尔.数字.字符串.数组和对象这几种数据类型,所以JSON有一定局限性.例如,JSON没 ...

  8. curl: (60) SSL certificate problem: unable to get local issuer certificate 错误

    今天同事做微信管理的项目,请求接口返回如下错误SSL certificate problem: unable to get local issuer certificate. 此问题的出现是由于没有配 ...

  9. 无法启动MYSQL服务”1067 进程意外终止”解决的方法——汇总及终极方法

    自己一開始依照百度经验里的方法--<MySQL下载安装.配置与使用(win7x64)>去安装和配置,可是到后面步骤总是出现1067代号的错误. 慢慢折腾去解决. 这里汇总各种导致mysql ...

  10. linux-git服务搭建

    第一步,安装git: 源码安装参考:http://www.cnblogs.com/syuf/p/9151115.html 第二步,创建一个git用户,用来运行git服务: $ sudo adduser ...