一、UGA由哪几部分组成?
由上述图片可知,
一个会话里如果处理的是SQL语句,那么在shared pool中就有该SQL语句对应的Shared Areas,该Shared Areas的类型为Shared SQL Areas,在该会话对应的进程对应的uga中,就有该SQL语句对应的Private Areas,该Private Areas的类型为PrivateSQL Areas。当然由于当一个SQL语句执行完毕后它对应的PrivateSQL Area也会释放掉,又一个会话里同时只有一个SQL语句执行,所以该会话对应的进程对应的uga中始终最多只有一个Private SQL Area存在。
一个会话里如果处理的是 PL/SQL programunits,那么在shared pool中就有该 PL/SQL program units对应的Shared Areas,该Shared Areas的类型为SharedPL/SQL Areas,在该会话对应的进程对应的uga中,就有该SQL语句对应的Private Areas,该Private Areas的类型为PrivatePL/SQL Areas。当然由于当一个PL/SQL program units执行完毕后它对应的Private SQL Area也会释放掉,又一个会话里同时只有一个PL/SQL program units执行,所以该会话对应的进程对应的uga中始终最多只有一个Private PL/SQLAreas存在。
由此可知,uga里必然包括session memory,而private sqlarea这个部分是当有SQL语句运行时存在于uga里,PrivatePL/SQL Area也是如此。
如果oracle还安装了OLAP组件,那么uga里也必有theOLAP pool。
uga组成部分结论的得出过程:
Pga和uga分别包含哪些部分?
当uga处于pga中(专用服务器模式)时,两者的分别包含哪些部分是否很清楚:uga全部处于pga中,uga包括session memory(记录会话信息)和私有sql区(包括the persistent area和 the runtime area(包括sql工作区和query execution stateinformation(即记录SQL语句执行进度的部分)两部分)两部分)。
当uga处于sga中(共享服务器模式)时,两者的分别包含哪些部分分别可理解为以下三种说法:
首先说明的是,按照oracle11gR2官方文档里的图示(http://docs.oracle.com/cd/E11882_01/server.112/e40540/memory.htm#i14490),sql工作区不包含在私有sql区的,uga就是图示中的session memory。按照oracle10g官方文档的说法,sql工作区是包含在私有sql区的。
Memory Area |
Dedicated Server |
Shared Server |
Nature of session memory |
Private |
Shared |
Location of the persistent area |
PGA |
SGA |
Location of part of the run-time area for |
PGA |
PGA |
Location of the run-time area for DML/DDL statements |
PGA |
PGA |
再参考上述来自oracle11gR2官方文档里的表格(http://docs.oracle.com/cd/B19306_01/server.102/b14220/memory.htm#i14490),可理解出三种说法。
第一种,uga就是图示中的session memory,uga处于sga中,而thepersistent area也处于sga中,那么the persistent area还是pga的一部分吗?还是说
第二种,上述表格中处于sga里的都是uga的组成部分。
第三种,uga包括session memory和private sql area两部分,当uga对应的进程是共享服务器进程时,那么uga分成两块,分别放在pga和sga上。
个人倾向认同第三种。
oracle10gR2官方文档对Library Cache解释:
LibraryCache
The librarycache includes the shared SQL areas, private SQL areas (in the case of a shared serverconfiguration), PL/SQL procedures andpackages, and control structures suchas locks and library cache handles.
从上面的表格可以看出,这里说的共享服务器模式时共享服务器进程的private SQL areas应该是部分在Library Cache上。
二、PGA上内存空间的分配与回收的方式
引言:
0、PGA上内存空间的分配与回收的过程可能会引起ora-4030。发生ora-4030,是可能因为操作系统的内存耗尽没有多余可以再分配了。
1、Pga中uga占了大头,uga中sql工作区又占了大头。
2、自动管理pga实际上调整的就是SQL工作区域(SQL Work Area)。
3、从V$PROCESS_MEMORY中字段CATEGORY
上可以看出
pga上内存空间分别用于什么用途,即pga上内存空间可以分成包括Freeable在内的六种类型。
正文
1、
从上面可得出如下结论:
无论是手动管理pga(的内存分配回收),还是自动管理pga(的内存分配回收),假设当一个进程产生时它对应的pga分配的空间大小为A,使用的空间大小为B,则当该进程运行一SQL语句时,要用到sql工作区,故而此时pga分配的空间大小和使用的空间大小就要变大,即pga分配的空间大小变为C,使用的空间大小变为D。
而当该SQL语句执行完毕后,就会释放sql工作区。此时,在手动管理pga(的内存分配回收)模式下,sql工作区所释放的空间就会释放给pga,故pga分配的空间大小依然为C,使用的空间大小变为B。在自动管理pga(的内存分配回收)模式下,sql工作区所释放的空间就会释放给操作系统,故pga分配的空间大小变为A,使用的空间大小变为B。
在手动管理pga(的内存分配回收)模式下,uga(包括其中的sql工作区)和cga所需的内存分配是从原本已有分配的pga上分配,如果原来操作系统给该pga分配的内存空间中不能分配出uga(包括其中的sql工作区)和cga所需的内存空间,则pga会先向操作系统申请内存分配给自己,再之后分配给uga(包括其中的sql工作区)和cga所需的内存。所以,释放的sql工作区所占的内存空间回收给pga,故而会产生pga内存空间可能一直增大的情况。
在自动管理pga(的内存分配回收)模式下,uga(包括其中的sql工作区)和cga所需的内存分配是直接从操作系统上分配,而不是从原本已有分配的pga上分配的,所以,释放的sql工作区所占的内存空间回收给操作系统,故而不会产生pga内存空间可能一直增大的情况,而有增有减。当然,这些从操作系统上分配的uga(包括其中的sql工作区)和cga的内存空间加上原本已有分配的pga内存空间,就成为该pga内存空间的新值,从V$PROCESS上的字段 PGA_ALLOC_MEM(或是PGA_USED_MEM)有增减变化这一现象或是从V$PROCESS_MEMORY上字段 CATEGORY 比如为SQL时 字段ALLOCATED(或是USED)有增减变化这一现象可以看出。
2、一个进程在视图V$PROCESS_MEMORY上各个字段CATEGORY值对应的ALLOCATED值之和,等于该进程在视图V$PROCESS上字段PGA_ALLOC_MEM值。同理,一个进程在视图V$PROCESS_MEMORY上各个字段CATEGORY值对应的USED值之和,等于该进程在视图V$PROCESS上字段PGA_USED_MEM值。
一个进程在视图V$PROCESS_MEMORY上字段CATEGORY值为Freeable对应的ALLOCATED值,等于该进程在视图V$PROCESS上字段PGA_FREEABLE_MEM
值。
PGA_FREEABLE_MEM
字段的值。但是实际上,发现不是这样,看到自己电脑上的显示的
V$PROCESS结果里,PGA_FREEABLE_MEM
字段的值都是为0,而
PGA_ALLOC_MEM字段减去 PGA_USED_MEM 字段 所得的差值都不是0。因为内存空间的分配和使用这两个概念是软件设计中常用的管理内存空间的手段。例如,创建一个表时,会分配以一个区段大小为单位的整数倍的空间给该表,而当向表中添加数据时(也就是使用该表时),则是按一个oracle数据块的空间大小为单位来使用,即按数据块大小来添加数据的。再如,window下用的记事本文件都是先分配一定大小(假设为A)的空间,如果使用该记事本文件的大小超过了该分配的空间,则又会再分配一定大小(也为A)的空间给该记事本文件。如下图所示:
PGA_FREEABLE_MEM
字段表示什么呢?
我们可以从对
V$PROCESS_MEMORY中字段CATEGORY
的解释中得知:
CATEGORY
都有自己的ALLOCATED和USED属性。只是还不知道在什么情况下一个进程对应的pga里的
Freeable是不为0。因为在V$PROCESS_MEMORY中CATEGORY
例如为SQL,假如一个sql工作区释放时,则其对应的ALLOCATED和USED属性值也会下降,但是这些释放的空间似乎不是放到CATEGORY为
Freeable的这里,它对应的ALLOCATED和USED属性值还是为0.
视图V$PGASTAT 上的字段total freeable PGA memory的值等于数据库当前各个进程在视图V$PROCESS上字段PGA_FREEABLE_MEM
值之和。
注释:
1、pga内存主要用于排序(当一个SQL语句中有排序操作时)等操作,因为pga内存的大部分空间为SQL工作区所占。
2、pga中不是有CGA是用于例如分析调用、提取调用等(暂时存放的结果集)吗?那么一个没有带有排序等操作的SQL语句执行时,是否会把结果集先存放在CGA中?可以通过如下方法验证:
在运行一个没有带有排序等操作的SQL语句期间,查看v$process的use字段是否变大,或是查看v$process_memory的cartory字段为other时对应的use字段是否变大?