本文由 dbaplus 社群授权转载。
我们在日常工作中,就像西天取经的僧人,总是会遇到各式各样的“妖怪”。这些“妖怪”总是一个又一个的阻挡在我们面前,你必须想办法击败它们。
听说小A同学最近遇到了一个很妖的问题,就这个问题我们来采访一下小A同学。
小B:你觉得RAC GC问题一般在什么情况下会产生?
小A:这个问题嘛其实很简单,我们要先从Oracle RAC的机制说起,RAC是一种共享磁盘的体系结构,多个服务器上的实例会同时打开数据库,并缓存磁盘中的数据。而当在一个节点上执行SQL,需要请求的buffer在remote实例上时,就会使用心跳进行传输。此时在本地节点上可能就会观察到GC类的等待事件。一般大量GC问题都是应用交叉访问引起的。
小B:那这一次的GC问题是应用交叉访问导致的吗?
小A:这次并不是,因为很多时候我们观察到系统权限类的SQL语句也在等待大规模的gc buffer busy acquire。
小B:系统语句?
小A:对,就是下面这个语句,他也产生了很多的GC。
select event,p1,p2,p3 from v$session where sql_id='05uqdabhzncdc'
EVENT P1 P2 P3
---------------------------------------------------------------- ---------- ---------- ----------
gc buffer busy acquire 1 46842 1
gc buffer busy acquire 1 46842 1
gc buffer busy acquire 1 46842 1
gc buffer busy acquire 1 46842 1
gc buffer busy acquire 1 46842 1
gc buffer busy acquire 1 46842 1
gc cr request 1 46842 1
gc buffer busy acquire 1 46842 1
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 05uqdabhzncdc, child number 1
-------------------------------------
select role# from defrole$ d,user$ u where d.user#=:1 and
u.user#=d.user# and u.defrole=2 union select privilege# from sysauth$
s,user$ u where (grantee#=:1 or grantee#=1) and privilege#>0 and not
exists (select null from defrole$ where user#=:1 and
role#=s.privilege#) and u.user#=:1 and u.defrole=3
Plan hash value: 552533229
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 7 (100)| |
| 1 | SORT UNIQUE | | 2 | 30 | 7 (29)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | NESTED LOOPS | | 1 | 14 | 2 (0)| 00:00:01 |
|* 4 | TABLE ACCESS CLUSTER| USER$ | 1 | 7 | 1 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | I_USER# | 1 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | I_DEFROLE1 | 1 | 7 | 1 (0)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 16 | 2 (0)| 00:00:01 |
|* 8 | TABLE ACCESS CLUSTER| USER$ | 1 | 7 | 1 (0)| 00:00:01 |
|* 9 | INDEX UNIQUE SCAN | I_USER# | 1 | | 1 (0)| 00:00:01 |
| 10 | INLIST ITERATOR | | | | | |
|* 11 | INDEX RANGE SCAN | I_SYSAUTH1 | 1 | 9 | 1 (0)| 00:00:01 |
|* 12 | INDEX UNIQUE SCAN | I_DEFROLE1 | 1 | 7 | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("U"."DEFROLE"=2)
5 - access("U"."USER#"=:1)
6 - access("D"."USER#"=:1)
8 - filter("U"."DEFROLE"=3)
9 - access("U"."USER#"=:1)
11 - access((("GRANTEE#"=:1 OR "GRANTEE#"=1)) AND "PRIVILEGE#">0)
filter( IS NULL)
12 - access("USER#"=:1 AND "ROLE#"=:B1)
小B:这个语句感觉没什么问题啊,这是查数据字典权限的,执行计划很好,关键表走的UNIQUE SCAN,应该很快就返回结果的。
小A:是的,正常情况都是秒出结果的,并不会产生GC等待。但是我们这个有点小异常,经常看到100-200个GC等待事件。