数据库有时会遇到大量的进程发生'enq: ss - contention'等待,持续5到10分钟,然后自动消失。从字面上看,'SS'是Sort Segment:
select * from v$lock_type where type='SS'
TYPE NAME ID1_TAG ID2_TAG IS_USER DESCRIPTION
--------------------------- ---------------------------------- -------------------------- --------------------
SS Sort Segment tablespace # dba NO Ensures that sort segments created during parallel DML operations aren't prematurely cleaned up
为何大量的进程需要等待Sort Segment enqueue呢?
从ASH的信息看,Sort Segment enqueue的持有者1581也是一个用户进程,他在等待'DFS lock handle'
5931 1 WAITING 1581 2 JDBC Thin Client dfcdxr0v3hn6n DFS lock handle 1128857605 14 2 26522266 147 1370406 N N
1674 1 WAITING 5931 1 JDBC Thin Client dfcdxr0v3hn6n enq: SS - contention 1397948422 6 2 142364 25 147677 N N
1772 1 WAITING 5931 1 JDBC Thin Client dfcdxr0v3hn6n enq: SS - contention 1397948422 6 2 140883 131 3809055 N N
1852 1 WAITING 5931 1 JDBC Thin Client dfcdxr0v3hn6n enq: SS - contention 1397948422 6 2 19434636 102 1265728 N N
<=========session 5931 是阻塞者,在等 'DFS lock handle','DFS lock handle'的持有者是节点2上的session 1581 .
从DFS lock handle的P1和P2可以看出他为何申请DFS lock handle,
<========DFS lock handle P1=1128857605 P2=14 P3=2
P1 DEC1128857605 =>HEX 43490005 <======CI enqueue
P2=14 <===========Release unused space of the sort segments. Handled by SMON
这是一个Cross Instance(CI)请求,请求的目的是释放未使用的sort segments,也就是清理TEMP表空间。
节点2上的session 1581 是DBW0:
2016-12-07 16:27:27 db file parallel write 1581 2 WAITING oracle@gx-db02-p780 (DBW0)
所以,节点1上的应用进程在等节点2上的DBW0清理TEMP表空间。
wait a minute,为何节点1的进程要等节点2的DBW0,他们为什么不请求本地的DBW0?
在RAC中,TEMP表空间是在各个节点间共享的(当然,其他所有的表空间都一样),但是TEMP表空间会在各个节点有缓存,可以通过以下视图查询到TEMP在各个节点的使用情况:
select inst_id, tablespace_name, blocks_cached, blocks_used from gv$temp_extent_pool;
如果一个节点缓存的TEMP blocks耗尽,会请求另一个节点释放一些未使用的TEMP给他用,释放的过程中会较长时间等待enq: ss - contention,这是一个正常的行为。