Oracle序列sequence cache nocache、RAC

 

一、问题描述:新增了个表,上了生产环境之后,发现ID跳号且穿插,如图1所示。   而测试环境只是跳号,如图2所示。

                               

                     图1  生产环境                                                                        图2  测试环境

 

二、为什么?    看建表时的创建序列的sql,如图

       

 

 

三、Oracle部署RAC 及 sequence cache问题:

        原来是 sequence  cache 的问题数据库是rac的,会缓存4000的seq段,两个机头都会有写入,所以ID会跳。

        为什么生产环境会出现这种问题:因为测试环节并没有真正完全模拟生产环境,没有部署RAC。

      1. 没有部署RAC的测试环境:如果按照流水号从小到大,数据入库时间不连续,并且流水号跳号,比如从1、2直接到4001,中间丢了3~4000。 然后继续4001、4002直接跳到8001。如开始的图2。

      2. 部署了RAC的生产环境:如果按照数据入库时间从小到大,流水号跳号并且是穿插,比如从1直接到4001,然后是2、3然后是4002,如开始的图1。

      分析:RAC有2个节点,节点1和节点2。

               假设某个表的Sequence从1开始,cache4000个。 一开始请求从节点1拿流水号,使得节点1缓存20个流水号(1~4000),在使用了1之后,请求被切到节点2,然后节点2也缓存4000个流水号(4001~8000),在使用了4001之后请求再被切回节点1使用2、3,再切回节点2使用4002。如此造成流水号穿插跳号情形。

        Sequence只能保证唯一,不能保证连续(即可能跳号,比如share_pool被刷或宕机后,原cache的流水号将丢失。还有就是事务回滚也会导致流水号跳号)。

       而我这里遇到的场景要特殊,是穿插跳号,而不是单向跳号,情况更严重。(注:解决穿插跳号问题,可以使用nocache)因此如果我们的sql里面对流水号有一些max,min,>=、<=等等类型的操作,那么可能就会有问题。  但这个表并没有涉及到操作ID,所以就不存在问题了。但希望小伙伴们在设计表的时候,要预先考虑这一情况。

 

四、Oracle序列sequence 的 cache 和 nocache 区别:

      cache:oracle会预先在缓存里面放置一些sequence,这样存取的快些。 缓存里面的取完后,oracle自动再取一组到cache。使用cache可能会跳号。 写入时间不连续会发生跳号。这里描述发生跳号的另一种情况:比如数据库突然不正常down掉(shutdown abort),cache中的Sequence就会丢失。  举个例子:比如你的cache中sequence有4000个,那当你sequence取到2007时突然断电,那么在你重启数据库后,sequence的值将从4001开始。

       nocache:此时oracle不会预先在内存里面存放sequence,当然这也就可以避免数据库不正常down掉的sequence丢失。 不过也会产生一些问题:创建nocache   sequence在高并发访问时,容易导致row cache lock等待事件,主要原因是每次获取nextval时都需要修改rowcache中的字典信息。使用nocache  sequence,还会导致下面的问题:由于每次修改字典信息都需要commit,可能导致log file sync等待,nocache sequence在RAC环境下,会对基于sequence生成的列创建的索引造成实例间大量索引块争用。
                基于以上问题,避免创建nocache sequence

 

      sequence相关保护机制

               row cache lock:在调用sequence.nextval情况下需要修改数据字典时发生,对应row cache lock事件。
               SQ lock:在内存缓存(并非rowcache)上获取sequence.nextval时发生,对应enq:SQ-contention事件。
               SV lock:RAC环境下获取cache+order属性的sequence.nextval时发生,对应DFS lock handle事件。

 

       什么时候使用cache?什么时候使用nocache?

             个人感觉应该尽量使用cache,因为现在的数据库很多都是在高并发的情况下运行的,首先这样可以高性能,并且也不会产生row cache lock等待事件。可能有些人会担心数据库不正常的down掉会产生序列号间断,但这也是很少的情况。当然如果你的业务要求是绝不能产生间断的序列号,那就要使用nochache了。

 

 

       说明:以上是本人做项目遇到的实际问题及所想所得,如有错误之处,还请指出,共同学习,嘿嘿。

 

 

 

 

 

 

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值