平台人生
作者平台人生·2018-01-05 17:07
软件开发工程师·平台人生

序列相关等待事件解析

字数 1852阅读 5160评论 3赞 5

作者:杨涛


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

1序列相关基本概念

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

测试1:ordered和noorder测试
首先我们创建一个noorder属性的序列
微信图片_20180105165751.jpg

微信图片_20180105165751.jpg

在节点一调用该序列:
微信图片_20180105165818.jpg
微信图片_20180105165818.jpg

然后在节点二调用该序列:
微信图片_20180105165844.jpg
微信图片_20180105165844.jpg

我们发现节点一上序列取值是顺序的,而节点二是从序列的cache值之后开始取值的。
然后我们创建一个order属性的序列
微信图片_20180105165905.jpg
微信图片_20180105165905.jpg

在一节点调用
微信图片_20180105165926.jpg
微信图片_20180105165926.jpg

在二节点调用
微信图片_20180105165947.jpg
微信图片_20180105165947.jpg

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

测试2:序列取不同cache值时候的性能差异测试
我们分别创建nocache、cache值为100和cache值为10000的三个序列
微信图片_20180105170019.jpg

微信图片_20180105170019.jpg

用如下脚本分别用三个序列取10万个值,耗时统计如下
微信图片_20180105170039.jpg
微信图片_20180105170039.jpg

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

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

与序列相关的等待事件有三个row cache lock、enq:SQ-contention和enq: SV-contention。下边我们分别模拟下这三个等待事件,然后总结如果遇到大量的这类等待事件该如何处理。
我们可以通过如下SQL查看SQ和SV这两种锁的解释。
微信图片_20180105170119.jpg

微信图片_20180105170119.jpg

测试1:row cache lock序列等待模拟
创建一个NOCACHE的序列,并使用NOORDER属性
微信图片_20180105170156.jpg

微信图片_20180105170156.jpg

微信图片_20180105170211.jpg
微信图片_20180105170211.jpg

分别在三个会话执行如下sql
微信图片_20180105170233.jpg
微信图片_20180105170233.jpg

执行asql.sql
微信图片_20180105170254.jpg
微信图片_20180105170254.jpg

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

测试2:enq: SQ - contention模拟
创建一个CACHE为5的序列,并使用NOORDER属性
微信图片_20180105170328.jpg

微信图片_20180105170328.jpg

分别在三个会话执行如下sql
微信图片_20180105170347.jpg
微信图片_20180105170347.jpg

执行asql.sql
微信图片_20180105170407.jpg
微信图片_20180105170407.jpg

有较小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属性
微信图片_20180105170436.jpg

微信图片_20180105170436.jpg

微信图片_20180105170449.jpg
微信图片_20180105170449.jpg

分别在三个会话执行如下sql
微信图片_20180105170519.jpg
微信图片_20180105170519.jpg

执行asql
微信图片_20180105170546.jpg
微信图片_20180105170546.jpg

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

3小结

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

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

5

添加新评论3 条评论

JeansonJeanson软件开发工程师中科信息
2018-01-09 10:15
不错的经验
wuwenpinwuwenpin软件开发工程师南京
2018-01-06 10:07
不错的经验
灰色轨迹灰色轨迹技术经理城商行
2018-01-06 08:32
不错的经验
Ctrl+Enter 发表

本文隶属于专栏

作者其他文章

相关文章

相关问题

相关资料

X社区推广