RAC环境中共享池很大一部分被gcs和ges资源所占用,一般来说这些资源对象都是永久的(perm)的,所以我们无法期待LRU或flush shared_pool操作能够清理这些资源。
在使用大缓存(large buffer cache)的RAC实例环境中,查询v$sgastat内存动态性能视图时总是能发现'gcs resources'、'gcs shadows'、' ges resource'、'ges enqueues '这些组件占用了共享池中的大量内存,为了避免shared pool出现著名的ORA-04031错误,Oracle推荐在RAC环境中设置较大的shared_pool_size初始化参数,此外显示地设置较大的GCS和GES资源结构的初始化分配数(INITIAL_ALLOCATION)也有利于避免ORA-4031。
这些控制GES和GCS资源结构初始化分配数量的参数主要包括:
- _gcs_resources number of gcs resources to be allocated GCS Resources Number of GCS resource structures determined by
_gcs_resources parameter
Stored in segmented array
Externalized in X$KJBR
Number of free GCS resource structures in X$KJBRFX
- _gcs_shadow_locks number of pcm shadow locks to be allocated GCS Enqueues (Shadows/Clients) Number of GCS enqueue structures determined by _gcs_shadow_locks parameter Stored in segmented array
Externalized in X$KJBL
Number of free GCS enqueue structures in X$KJBLFX
- _lm_ress number of resources configured for cluster database LM_RESS controls the number of resources that can be locked by each lock manager instance. These resources include lock resources allocated for DML, DDL (data dictionary locks), data dictionary, and library cache locks plus the file and log management locks. Stored in heap
Externalized in X$KJIRFT
- _lm_locks number of enqueues configured for cluster database Stored in segmented array
Externalized in X$KJILKFT
为了更好地在RAC环境中设置shared_pool_size共享池的大小(手动设置该参数并不会disable AMM or ASMM),我们很有必要评估大量初始化分配的全局资源本身将占用shared pool多大的空间。
我们可以通过v$resource_limit视图了解这些GES、GCS全局资源的分配情况:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
www.oracledatabase12g.com
SQL> select * from v$resource_limit where resource_name in ('gcs_resources', 'gcs_shadows','ges_ress','ges_locks');
RESOURCE_NAME CURRENT_UTILIZATION MAX_UTILIZATION INITIAL_ALLOCATION LIMIT_VALUE
------------------------------ ------------------- --------------- ------------------------- ------------------
ges_ress 7223 7486 1000000 UNLIMITED
ges_locks 4944 5027 1000000 UNLIMITED
gcs_resources 4021 4021 114466 114466
gcs_shadows 3925 3925 114466 114466
可以通过v$sgastat视图了解这些全局资源占用了多少空间:
select *
from v$sgastat
where name in
('ges resource ', 'ges enqueues', 'gcs resources', 'gcs shadows');
POOL NAME BYTES
------------ -------------------------- ----------
shared pool gcs resources 16483232
shared pool gcs shadows 11904560
shared pool ges enqueues 47809680
shared pool ges resource 288405768
单个gcs_resources结构大约占用120 bytes
单个gcs_shadows 结构大约占用72 bytes
单个ges_resource 结构大约占用288 bytes
我们可以使用一下初步估算GES、GCS资源结构将至少占用多大的共享池资源:
'gcs_resources' = initial_allocation * 120 bytes = "_gcs_resources parameter" * 120 bytes
'gcs_shadows' = initial_allocation * 72 bytes = "_gcs_shadow_locks parameter" * 72 bytes
'ges_resource'= initial_allocation * 288 bytes = "_lm_ress parameter " * 288 bytes
注意这里计算出的仅仅是理论的最小值,实际值因为内存分配的机制所以必然会远大于计算值
如上例中 gcs resources = 114466 * 120 =13735920 << 实际值的16483232
gcs_shadows = 114466 * 72 = 8241552 << 实际值的11904560
ges_resource = 1000000 * 288 = 288000000 < 实际的288405768
一般来说我们将计算值 * 160% 后可以得出一个较为客观的估算值。
注意以上公式只是为我们在RAC环境中调优共享池的大小提供参考的依据。当我们观察v$resource_limit视图并认为需要提高GES、GSC资源的初始化分配数目时,可以参照上述方式估算出必要的shared_pool_size或sga_target大小。