资讯专栏INFORMATION COLUMN

oracle自增序列跳号,sequence跳号问题及解决办法

IT那活儿 / 2914人阅读
oracle自增序列跳号,sequence跳号问题及解决办法


01

问题及现象描述

由于数据库重启、刷新、奔溃等原因,导致sequence缓存数据丢失,查询时出现跳号现象,即从下一个号开始。
我们一起来看一个样例:
--创建序列

</>复制代码

  1. CREATE SEQUENCE MYTEST.S_TEST

    START

    WITH 1

    INCREMENT

    BY 1

    NOMINVALUE

    MAXVALUE

    10000

    NOCYCLE

    CACHE 20

    NOORDER

    SQL> select S_TEST.nextval from dual;

    NEXTVAL

    ----------

    1

    SQL> select S_TEST.nextval from dual;

    NEXTVAL

    ----------

    2

    SQL> select S_TEST.nextval from dual;

    NEXTVAL

    ----------

    3
刷新共享池,刷新共享池会使所有的没有使用DBMS_SHARED_POOL.KEEP固定的对象全部被清除,所以共享池刚刚刷新的时候,SQL和PL/SQL的执行效率会略微下降

</>复制代码

  1. SQL> ALTER SYSTEM FLUSH SHARED_POOL;
系统已更改。
--由于cache的20个序列号已经从共享池中被清除,下次再取序列的nextval值取的是21。

</>复制代码

  1. SQL> select S_TEST.nextval from dual;
    NEXTVAL
    ----------
    21
关于序列设置cache之后跳号问题的原因:cache会把sequence缓存在lb cache中,在lb cache中对对象的age out是基于lru算法的,如果cache 20,会把这个序列每次取的时候取出来20个,然后再在lb cache中一个一个用,但是如果在用完这20个之前,这个序列被aged out了,那么没用的那些数就丢掉了,而下次再去从dd取出sequence的时候就会去取上次那20个+1的号为开始,再来20个。这就是产生断号的原因


02

如何解决

为了避免上述情况,ORACLE给我们提供了把SEQUENCE KEEP到SHARED POOL(dbms_shared_pool包)中的方法,这样就保证了SEQUENCE的CACHE不会被交换出去,从而避免了这种情况的发生。
如果将对象固定在内存中,那么在下一次关闭数据库之前,这个对象就不会失效或者被清空。还需要考虑的是,Metalink的注意事项61760.1:DBMS_SHARED_POOL将被创建为用户SYS。其他用户不拥有这个包。需要访问这个包的任何用户都必须由SYS授予执行权限。如果在SYS模式中创建这个包并在不同的模式中运行示例代码,则首先必须给用户赋予DBMS_SHARED_POOL上的EXECUTE权限。
默认情况下dbms_shared_pool包是不在系统中的,需要运行$ORACLE_HOME/rdbms/admin/dbmspool.sql进行创建。

</>复制代码

  1. SQL> desc dbms_shared_pool;
    ERROR:
    ORA-04043: 对象 dbms_shared_pool 不存在
--创建

</>复制代码

  1. SQL> @E:oracleRDBMSADMINdbmspool.sql
程序包已创建。
授权成功。
视图已创建。
程序包体已创建。
--查看包对象

</>复制代码

  1. SQL> desc dbms_shared_pool;
--授权

</>复制代码

  1. SQL> grant execute on dbms_shared_pool to MYtest;
授权成功。

</>复制代码

  1. SQL> create synonym MYtest.dbms_shared_pool for dbms_shared_pool;
同义词已创建。
procedure keep参数的解释:
exec dbms_shared_pool.keep
keep共有两个参数,flag代表前一个参数的类型,
如果不输入,则默认为package/procedure/function中的一个;

</>复制代码

  1. procedure keep(name varchar2, flag char DEFAULT P)
    name
    -- The name of the object to keep. There are two
    kinds of objects:
    -- PL/SQL objects, triggers, sequences, types and
    Java objects,
    -- which are specified by name, and
    -- SQL cursor objects which are specified by a two-part number
    -- (indicating a location in the shared pool). For
    example:
    -- dbms_shared_pool.keep(scott.hispackage)
    -- will keep package HISPACKAGE, owned by SCOTT. The
    names for
    -- PL/SQL objects follows SQL rules for naming objects (i.e.,
    -- delimited identifiers, multi-byte names, etc. are allowed).
    -- A cursor can be keeped by
    -- dbms_shared_pool.keep(0034CDFF, 20348871, C)
    -- The complete hexadecimal address must be in the first 8
    characters.
    -- The value for this identifier is the concatenation of the
    -- address and hash_value columns from the v$sqlarea
    view. This
    -- is displayed by the sizes call above.
    -- Currently TABLE and VIEW objects may not be keeped.
    flag
    -- This is an optional parameter. If the parameter
    is not specified,
    -- the package assumes that the first parameter is the name of a
    -- package/procedure/function and will resolve the
    name. Otherwise,
    -- the parameter is a character string indicating what kind of
    object
    -- to keep the name identifies. The string is case
    insensitive.
    -- The possible values and the kinds of objects they indicate are
    -- given in the following table:
    -- Value Kind of Object to keep
    -- ----- ----------------------
    -- P package/procedure/function
    -- Q sequence
    -- R trigger
    -- T type
    -- JS java source
    -- JC java class
    -- JR java resource
    -- JD java shared data
    -- C cursor


安装成功后,执行exec dbms_shared_pool.keep(数据库用户名.sequence名称, Q);执行成功即可;

若安装不成功,试试看执行$ORACLE_HOME/rdbms/admin/utlrp.sql;
--测试结果
S_TEST和S_TEST2序列都是设置cache20,将s_test序列keep到shared pool中。

</>复制代码

  1. SQL> select S_TEST.nextval from dual;
    NEXTVAL
    ----------
    24
    SQL> select S_TEST.nextval from dual;
    NEXTVAL
    ----------
    25
    SQL> select S_TEST2.nextval from dual;
    NEXTVAL
    ----------
    1
    SQL> exec dbms_shared_pool.keep(s_test,q);
PL/SQL 过程已成功完成。

</>复制代码

  1. SQL> select S_TEST2.nextval from dual;
    NEXTVAL
    ----------
    21
    SQL> select S_TEST.nextval from dual;
    NEXTVAL
    ----------
    26
-- dbms_shared_pool.unkeep的作用是取消已经keep在shared pool中的对象

</>复制代码

  1. SQL> exec
    dbms_shared_pool.unkeep(s_test,q);
PL/SQL 过程已成功完成。

</>复制代码

  1. SQL> select S_TEST.nextval from dual;
    NEXTVAL
    ----------
    27
    SQL> alter system flush shared_pool;
系统已更改。

</>复制代码

  1. SQL> select S_TEST.nextval from dual;
    NEXTVAL
    ----------
    41



本 文 原 创 来 源:IT那活儿微信公众号(上海新炬王翦团队)


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129714.html

相关文章

  • 基于 oracle 的 flask 项目(一)——配置项目

    摘要:一般印象,项目适合做一些短小精悍的项目,特别是与等数据库结合很是般配。生成报表,不同的查询结果生成不同的报表。配置从下载客户端,然后解压后放入自己指定的目录。指定数据库连接池的超时时间。 一般印象,flask 项目适合做一些短小精悍的项目,特别是与 sqlite、mysql 等数据库结合很是般配。但是在一些大公司,特别是一些金融行业等国企公司,还是以 oracle 居多,那么,这个小辣...

    xialong 评论0 收藏0
  • 使用SpringBoot-JPA进行自定义的保存批量保存

    摘要:既然行不通,或许可以考虑使用注解来自定义一个实现。仍旧提供给了使用者原始的使用方式利用来构造并执行。就像一样,使用者也可以自定义来执行,试试看,同样没有问题,再多的数据也可以被保存到数据库中批量保存的效果达到了。 更多精彩博文,欢迎访问我的个人博客 说明 SpringBoot版本:2.1.4.RELEASE java版本:1.8 文中所说JPA皆指spring-boot-starte...

    boredream 评论0 收藏0
  • 关于生成订单号规则的一些思考

    摘要:关于我为什么写这篇文章是因为今天在做订单模块的时候看到之前的上描述的年月日用户位企业位四位自增长数。背景对于其定订单的生成。个人的看法是主要是唯一,其他关于业务方面的不是太太重要。自增实现了用于将的值递增,并返回结果。 关于我为什么写这篇文章是因为今天在做订单模块的时候,看到之前的PRD上描述的年月日+用户id2位+企业id位+四位自增长数。然后竟被我反驳的突然改成了精确时间+4位自增...

    omgdog 评论0 收藏0
  • 探讨分布式ID生成系统

    摘要:结合对做如下调整的毫秒时间戳的数据逻辑分区以及的自增序列。为了解决这个问题,便引入了逻辑分区。参考文章批量插入返回自增的问题美团点评分布式生成系统 这里的博客版本都不会被更新维护。查看最新的版本请移步:http://neojos.com 全称Universally Unique Identifier,UUID占128bit,也就是16个英文字符的长度(16byte),需要强调的是,它...

    junbaor 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<