enq: SQ

来源:互联网 发布:苏德瓜分波兰 知乎 编辑:程序博客网 时间:2024/04/28 12:16

做巡检的时候遇到了enq: SQ - contention等待事件,咱来一步步分析awr报告找到问题所在。

Snap Id Snap Time Sessions         Cursors/Session Begin Snap: 1461112-Dec-17  14:00:09 24411.2 End Snap: 1461212-Dec-17  15:00:17 3129.9 Elapsed: 60.13 (mins) DB Time: 7,510.66 (mins) 

在快照期间,DB Time 7510.66分钟,对于cpu个数为80的服务器来说,DB占CPU资源的157%,瞬时负载较高。

同时我也查询了其他时间段的DB Time,CPU占用也就在80%左右,可以判断的是在12-Dec-17  14:00:09-12-Dec-17  15:00:17期间数据库一定发生了什么事情。



第一条便是enq:SQ - contention,占用了大部分的DB Time

然后查找enq:SQ - contention的MOS文档,很容易就找到其cause:

The most common cause is that one or more sequences are getting used heavily, and the cache size for those sequences may not be adequate for RAC

也就是说是由于sequence设置不合理导致


为了解决这个问题,我们来着重理解一下sequence的cache特性

sequence也就是我们说的序列号,一般来说建立sequence是为了完成所求变量的自增。在sequence中有非常关键的属性cache,cache就是sequence的缓存,当我们建立sequence的时候,就需要指定cache值(当然也有默认值),比如说当sequence从1一直nextval到20,这个时候缓存中的sequence值都取完了,必须重新取缓存值21,内存中的值也就到了21-40。

这个cache的问题有什么意义呢?

如果sequence定义为nocache,也就是不缓存,每次取nextval都会重新计算nextval的值,而不是直接从内存中读取,从性能上来讲这肯定效率较低。


为什么oracle不直接把默认值设置的很大?

首先内存肯定是有限的,为了一个sequence就牺牲数据库的内存也太不应该了。其次,为了安全。当oracle数据库宕机的时候,内存中的sequence cache也都找不到了,比如说cache值为10000,nextval已经取到了9999,内存中的cache值仍为1-10000,这个时候数据库宕机,内存中的数据找不回来了,数据库重新启动后业务的sequence重新取值,就得从1开始取,而不是10000。所有cache值设置的太大也不合适


了解了sequence,就能理解mos提供的解决办法:

1.尽量把非cache noorder的sequence设置成cache noorder

2.如果是cache noorder,且cache值小于100,设置成更大的值(cache默认值为20),mos建议值为10000.

(参考文档:High "enq: SQ - contention" waits in RAC (文档 ID 2156730.1))


马上查找了数据库中所有sequence的cache设定,很多用户都是设置的默认值20或者或者很小的值.

但是sequence有几百个,全部修改的话动作较大,找到问题sequence修改就足够了。

所以再继续看awr



从上面的TOP SQL和对应的SQL Text就可以看出,

在快照时间内,数据库一定发生了大量的插入操作,在插入操作中使用了大量的sequence,所以将这些sequence做出修改,enq:SQ - contention等待事件就会舒缓许多

原创粉丝点击