序列相关等待事件解析

JAN

05

对于高并发系统,尤其秒杀系统,很容易因为数据库序列使用不当造成应用堵塞,本次分享我们从数据库等待事件的角度解析下ORACLE数据库序列相关的等待事件,并总结序列使用的最佳实践。

01

序列相关基本概念

对于序列有两个重要的属性,一个是序列cache值大小,一个是序列的order属性,下面我们通过两个小测试说明这两个属性对序列的影响。

测试1:ordered和noorder测试

首先我们创建一个noorder属性的序列

在节点一调用该序列:

然后在节点二调用该序列:

我们发现节点一上序列取值是顺序的,而节点二是从序列的cache值之后开始取值的。

然后我们创建一个order属性的序列

在一节点调用

在二节点调用

对于ORDER属性的序列,在RAC的不同节点调用,序列值始终是连续的,跟序列的CACHE值无关。

测试2:序列取不同cache值时候的性能差异测试

我们分别创建nocache、cache值为100和cache值为10000的三个序列

用如下脚本分别用三个序列取10万个值,耗时统计如下

结果我们发现,cache值为100时耗时明显低于nocache,而cache值为10000比cache值为100耗时并没有提升很多,应通过测试对自己的序列选择合适的cache值。

02

与序列相关的几个等待事件

与序列相关的等待事件有三个row cache lock、enq:SQ-contention和enq: SV-contention。下边我们分别模拟下这三个等待事件,然后总结如果遇到大量的这类等待事件该如何处理。

我们可以通过如下SQL查看SQ和SV这两种锁的解释。

测试1:row cache lock序列等待模拟

创建一个NOCACHE的序列,并使用NOORDER属性

分别在三个会话执行如下sql

执行asql.sql

NOCACHE属性的序列,在调用SEQUENCE.NEXTVAL时候,会产生等待事件row cache lock。

测试2:enq: SQ - contention模拟

创建一个CACHE为5的序列,并使用NOORDER属性

分别在三个会话执行如下sql

执行asql.sql

有较小CACHE的序列,在多个会话调用SEQUENCE.NEXTVAL的时候,会因为获取SQ锁而产生争用,产生等待事件enq:SQ-contention。其原因是V$SESSION.AUDSID列值是利用序列创建的,Oracle在创建新的会话后,利用名为SYS.AUDSES$的序列的NEXTVAL来创建AUDSID值。Oracle 11g下SYS.AUDSES$的CACHE值默认为10000。

测试3:enq: SV - contention

创建一个CACHE为5的序列,并使用ORDER属性

分别在三个会话执行如下sql

执行asql

在RAC环境下,CACHE+ORDER属性的序列,在多个回话同时调用SEQUENCE.NEXTVAL的时候,会产生enq: SV-contention等待事件,应该尽量设置为NOORDER属性,并扩大其cache值。

03

小结

首先,尽量避免nocache序列的使用;其次,在RAC环境下,为避免SV锁的争用,应该尽量避免使用ORDER 属性,尤其避免ORDER+NOCACHE的组合;最后,在序列使用的并发量较高的情况下,可以尝试增大CACHE值来缓解锁争用,一般可以设定到5000左右。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180105G0JJBR00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券