Oracle内存管理之PGA
Oracle数据库实例启动时,就需要分配共享内存,启动后台进程,如何分配和设置共享内存参数,对于Oracle来说是非常重要的。不当的内存分配轻则影响性能,重则导致数据库故障。
Oracle数据库所使用的内存主要涉及两个方面:PGA和SGA。本章就Oracle的内存管理问题进行探讨。
PGA管理
PGA指的是程序全局区(Program Global Area),是服务器进程(Server Process)使用的一块包含数据和控制信息的内存区域,PGA是非共享的内存,在服务器进程启动或创建时分配(在系统运行时,排序、连接等操作也可能需要进一步的PGA分配),并为Server Process排他访问,所以PGA中的数据结构并不需要通过Latch来保护。
什么是PGA
进程的创建通常有两种方式:
(1)专用服务器模式(Dedicated Server)
在专用服务器模式下,Oracle会为每个会话启动一个Oracle进程,
(2)共享服务器模式(Share Server)
而在共享服务器模式下,通常在服务器端启动一定数量的服务器进程,然后由多个用户请求共享同一个Oracle服务进程
通常数据库都应当运行在专用服务器模式下。PGA的内容也依专用模式和共享模式而有所不同。
从内存分配和使用上PGA可以被分为两个区域:
(1) 固定PGA(Fixed PGA)
固定PGA和固定SGA类似,包含了大量原子变量、小的数据结构和指向可变PGA的指针,这些变量在源码中定义,在编译时分配,可以被认为是PGA的保留内存
(2) 可变PGA(Variable PGA)
可变PGA通过具体的内存Heap分配来实现,其空间分配与使用时可以变化的,通过内部视图X$KSMPP可以查询可变PGA的分配和使用情况。
可变PGA部分实际上是我们最为关注的PGA部分。虽然PGA的内容对于专用和共享模式会有所不同,但是通常来说,可变PGA由以下两部分组成。
(1) 会话内存(Session Area)
用于存储会话专有的信息,如登录信息、跟踪信息、Alter session命令修改的环境参数信息、会话拥有的角色信息等。
对于共享服务器模式,这部分内存是共享而非私有的
(2) 私有SQL区(Private SQL Area)
包含绑定变量信息、查询执行状态信息等。每个发出的SQL查询会话都拥有一块私有SQL区,对于专用服务器模式,这部分内存在PGA中分配,对于共享服务器模式,这部分内存在SGA中分配
私有SQL区以由以下两部分组成:
(1) 永久区域(Persistent Area)
这个区域包含绑定变量、数据类型转换等CURSOR的结构信息,在CURSOR被关闭时释放
(2) 运行时区域(Runtime Area)
Run-Time Area区域在SQL运行过程中使用,其大小依赖于SQL语句的操作方式,(Sort或者Hash-Join)、要处理的数据行数和每行记录集的大小,也就是要处理的数据越多执行处理的步骤越多,这块区域空间需求越大。如果是DML语句,SQL语句执行完毕这块区域就会释放;而如果是查询语句,则只有在整个结果集都传递给用户后,或者用户取消查询后这部分空间才会被释放。
一旦SQL语句处理完毕后,Run-Time Area就被释放,而Private SQL Area部分就可以被其他SQL语句重用,每次对Private SQL Area重用都必需重新初始化。
UGA(User Global Area)用户全局区
在共享服务器模式下,一个共享服务进程被多个用户进程共享,此时UGA是Share Pool或Large Pool的一部分,而在专用服务器模式下,UGA则是PGA的一部分。
不考虑Share Server模式,在Dedicated模式下,PGA与UGA关系,就如同Process和Session的关系,PGA是服务于进程的内存结构,包含进程信息;而UGA是服务于会话的,它包含的是会话的信息。
在UGA中包含如下信息:
(1) 打开游标的永久区域和运行区域
(2) 包的状态信息以及变量信息
(3) Java会话的状态信息
(4) 启用角色信息、跟踪事件
(5) 起作用的NLS参数
(6) 所有打开的database links
(7) 会话访问控制信息等
和PGA一样,UGA也由两组区域组成:
(1) 固定UGA区域
固定UGA包含了大约70个原子变量,小的数据结构以及指向UGA堆的指针
(2) 可变的UGA区域
UGA中的内存分配可以通过内部表X$KSMUP查询得到。UGA堆包含了一些固定表(X$表)的永久内存(依赖于特定参数的设置),如OPEN_CURSORS,OPEN_LINSK和MAX_ENABLED_ROLES。除此以外,大部分的UGA用于私有SQL区和PL/SQL区。
从Oracle9iR2开始,有一系列新的隐含参数被引入用于控制PGA的自动管理,这其中有一个关键的参数是_use_realfree_heap,当设置这个参数为true时,Oracle会为CGA、UGA单独分配堆,而不从PGA中分配。这的默认值为false,而当设置了pga_aggregate_target后,这的值自动被改为true。
_use_realfree_heap是自动管理PGA技术的关键技术变化,realfree代表实时释放。Oracle9i之前手工管理的PGA的主要问题在于,UGA缺省在PGA中分配,当会话执行了诸如排序、HASH-JOIN等操作,耗用了大量的PGA内存,而当会话执行完毕后,内存会释放给PGA而不是OS,在很多时候这会导致过度的PGA内存使用;从Oracle9iR2开始,自动的PGA内存管理当_use_realfree_heap为true时,当调用结束时将不必将内存返回给PGA而直接返回给OS,从而实现了更好的PGA内存分配与使用。
通过v$pgastat视图,可以查询PGA累计释放回OS的内存空间:
SQL> select name,value from v$pgastat where name like '%OS%';
NAME VALUE
------------------------------ ----------
PGA memory freed back to OS 149880832
CGA(Call Globall Araa)调用全局区
与其它的全局区不同,CGA的存在是瞬间的,只存在于调用过程中,而且无论UGA存在于PGA还是SGA,CGA都是PGA的SubHeap。
对于实例的一些低层次的调用(Low-Level Call)需要CGA,包括分析SQL语句、执行SQL语句以及获取查询结果都需要使用CGA。
在SQL执行过程中的每个递归调用都需要一个独立的CGA;在SQL语句的解析过程中,查询数据字典信息、对SQL进行语法及语义的解析、SQL的优化以及不同执行计划的评估都需要使用CGA。
当然,调用并不是只通过CGA中的数据结构来工作,实际上调用所需要的大部分的重要数据结构都来自UGA(如SQL AREA、PL/SQL AREA、Sort Area都存放在UGA中,因为这些结构在调用期间需要一直使用),CGA中只包含了调用以后可以被释放的数据。如CGA中包含了Direct I/O BUFFER、递归调用信息、表达式评估的堆栈信息等,此外,Java调用内存也在CGA中分配。
PGA管理技术的变迁
在Oracle9i以前的版本中,PGA由一系列的内存区域组成,这些区域包括主要由*_area_size参数控制。对于PGA内存的使用也是通过控制这些参数来实现。
但是这种独立管理的方式存在一个极大的弊端,以SORT操作为例,如果我们为了使特定的排序操作能够在内存中完成,可能需要设置较大的sort_area_size,但是由于进程的独立PGA内存难于回收和共享,这样可能导致过度的PGA内存消耗,所以合理设置和调整PGA在Oracle9i之前是一件比较复杂的事情;从Oracle9i开始,Oracle提供了一种新的PGA内存管理方法:自动化SQL执行内存管理(Automated SQL Execution Memory Management),也称为自动PGA管理,使用这个特性,Oracle可以在一个总体PGA使用限制下自动管理和调整SQL内存区,从而大大简化了DBA的工作,同时也提高了数据库的性能。
实现自动的PGA管理,Oracle引入了几个新的初始化参数:
(1) PGA_AGGREGATE_TARGET
这个参数用来指定所有session总计可以使用最大PGA内存,这个参数可以动态更改,取值范围从10M-4096G
(2) WORKAREA_SIZE_POLICY
这个参数用于开关PGA内存自动管理功能。该参数有AUTO和MANUAL两个选项,当设置为AUTO时,数据库使用自动内存管理功能,当设置为MANUAL时,则仍然使用之前的手工管理方式。缺省这个参数的值为AUTO
此外,需要注意的是,在不同的版本中,自动PGA管理的范畴不同:
(1) 在Oracle9i中,PGA_AGGREGATE_TARGET参数仅对专用服务器模式下有效,对共享服务器模式连接无效。
(2) 在Oracle10g中,在两种连接模式中都有效
参数的设置与内存的分配
PGA_AGGREGATE_TARGET参数同时限制全局PGA分配和私有工作区分配
在Oracle9i以及Oracle10gR1中,单个SQL操作内存使用存在如下限制:
(1) 对于串行操作,单个SQL操作能够使用的PGA内存按照以下原则分配
MIN (5%*PGA_AGGREGATE_TARGET,100MB)
此处5%*P_A_T实际上是由一个内部参数_smm_max_size决定的,该参数限制自动工作区模式下最大的工作区使用(maximum work area size in auto mode-serial)
(2) 对于并行操作,能够使用的PGA内存按照以下原则分配
30%*PGA_AGGREGATE_TARGET/DOP
在Oracle10gR2以及Oracle11g中,内存使用存在如下限制:
(1) 对于串行操作,能够使用的PGA内存按照以下原则分配
如果P_A_T<=500MB,则_smm_max_size = 20%*P_A_T
如果P_A_T在500MB和1000MB之间,_smm_max_size = 100MB
如果P_A_T在1001MB和2569MB之间,_smm_max_size = 10%*P_A_T
如果P_A_T>2560MB,则_smm_max_size = 262,060MB
(2) 对于并行操作,能够使用的PGA内存按照以下原则分配
50%*P_A_T/DOP
但是注意,当DOP<=5时,_smm_max_size限制生效,并行度超过5时另外一个限制并行的参数_smm_px_max_size才会生效
从Oracle10g开始的新的PGA管理算法受一个新增的隐含参数_newsort_enabled影响,如果该参数设置为False,则数据库会使用之前Oracle9iR2中的算法规则
1 select x.ksppinm NAME,y.ksppstvl VALUE,x.ksppdesc PDESC
2 from sys.x$ksppi x,sys.x$ksppcv y
3 where x.indx = y.indx
4* and x.ksppinm like '%&par%'
SQL> /
Enter value for par: newsort_enabled
old 4: and x.ksppinm like '%&par%'
new 4: and x.ksppinm like '%newsort_enabled%'
NAME VALUE PDESC
------------------------------ -------------------- ------------------------------------------------------------
_newsort_enabled TRUE controls whether new sorts can be used as system sort
要理解PGA的自动调整,还需要区分可调整内存(TUNABLE MEMORY SIZE)与不可调整内存(UNTUNABLE MEMORY SIZE)。可调整内存是由SQL工作区使用的,其余部分是不可调整内存。
启用了自动PGA调整之后,Oracle仍然需要遵循以下原则:
UNTUNABLE MEMORY SIZE + TUNABLE MEMORY SIZE <= PGA_AGGREGATE_TARGET
数据库系统只能控制可调整部分的内存分配,如果可调整的部分过小,则Oracle永远也不会强制启用这个等式。
另外,PGA_AGGREGATE_TARGET参数在CBO优化器模式下,对于SQL的执行计划会产生影响。Oracle在评估执行计划时会根据PGA_AGGREGATE_TARGET参数评估在SORT、HAS-JOIN或BITMAP操作时能够使用的最大内存或最小内存,从而选择最优的的执行计划。
对于PGA_AGGREGATE_TARGET参数的设置,Oracle提供这样一个建议方案:
(1) 对于OLTP系统
PGA_AGGREGATE_TARGET=(TOTAL PHYSICAL MEMORY * 80%)*20%
(2) 对于DSS系统
PGA_AGGREGATE_TARGET=(TOTAL PHYSICAL MEMORY * 80%)*(20~50)%
注:在某些OS上单个进程使用的的真实内存可能远大于在Oracle中看到的PGA大小,如AIX,在AIX上通常建议Oracle使用内存不超过物理内存的70%
这只是一个建议设置,具体的更进一步的优化应该根据具体的性能指标来调整。
伴随着这个新的特性的加入,可以在v$process和v$process_memory视图中获取具体的PGA内存消耗。
SQL在工作区中以3种方式执行:
(1) Optimal
优化方式,指所有的处理可以在内存中完成
(2) Onepass
大部分的操作可以在内存中完成,但是需要使用到磁盘操作
(3) Multipass
大量的操作需要产生磁盘交互,性能极差
通常对于PGA的优化的目标就是使得optimal的执行尽量高,也就是尽量在内存中完成所有排序操作;同时使得multipass操作尽量低。
如下所示:
SQL> l
1 select name,value,
2 100*(value/decode((select sum(value) from v$sysstat
3 where name like '%workarea executions%'),0,null,
4 (select sum(value) from v$sysstat
5 where name like '%workarea executions%'))) pct
6* from v$sysstat where name like '%workarea executions%'
SQL> /
NAME VALUE PCT
---------------------------------------- --------- ----------
workarea executions - optimal 17361 100
workarea executions - onepass 0 0
workarea executions - multipass 0 0
自动PGA管理实现原理
自动PGA管理采用反馈环(Feedback Loop)算法实现,其原理如下图所示:
Set of Active Work Area Profiles |
Register Workarea |
Get Workarea Size |
Active Statements |
Local Memory Manager |
WPn |
Global Memory Manager |
当活动进程开始执行SQL语句时,首先会通过Local Memory Manager注册一个Active Workarea Profile。
Workarea Profile是进程与内存管理器之间通信的唯一接口,Profile包含了这个Workarea的一系列属性。
Workarea Profile集通过Local Memory Manager维护,存储在SGA之中,由于Profile经常被更新,所以所有Active Profile基本可以反应当前PGA内存需要和当前正在使用的内存。有了这些Profile信息,后台的Global Memory Manager就可以计算出一个既能提供较好性能的Global Memory Bound,这个值用于限制单个进程使用的PGA内存上限;Global Memory Manager每隔3秒更新一次Memory Bound,Local Memory Manager得到Memory Bound后会计算出每个Active Segment所需要分配的PGA内存大小,在这里被称为Expect Size,然后每个Active Segment将会在自己所分配到的Expect Size内存中进行运算。
在以上流程中,Global Memory Manager并不直接参与PGA内存的分配,但是通过其计算得出的Global Memory Bound将影响所有进程的PGA分配。
Global Memory Manage由CKPT后台进程实现,如下所示。
SQL> select description,dest from x$messages where description like '%SQL%';
DESCRIPTION DEST
---------------------------------------------------------------- ----------------------------------------------------------------
SQL Memory Management Calculation CKPT
在Oracle10g以及11g中,可以通过v$sgastat视图来查询工作区的管理内存分配,如下:
SQL> select * from v$sgastat where name like 'work area%';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool work area tab 276576
伴随着新特性的引入,Oracle引入了一系列新的视图,如v$pgastat,内容如下:
SQL> select * from v$pgastat;
NAME VALUE UNIT
---------------------------------------------------------------- ---------- ------------
aggregate PGA target parameter 94371840 bytes
aggregate PGA auto target 68585472 bytes
global memory bound 18874368 bytes
total PGA inuse 18197504 bytes
total PGA allocated 42578944 bytes
maximum PGA allocated 76462080 bytes
total freeable PGA memory 5701632 bytes
process count 19
max processes count 28
PGA memory freed back to OS 212729856 bytes
total PGA used for auto workareas 0 bytes
maximum PGA used for auto workareas 5085184 bytes
total PGA used for manual workareas 0 bytes
maximum PGA used for manual workareas 0 bytes
over allocation count 0
bytes processed 498573312 bytes
extra bytes read/written 0 bytes
cache hit percentage 100 percent
recompute count (total) 11387
隐含参数_pga_max_size控制单进程串行操作PGA的使用上限,不能超过该参数的1/2。从Oracle10g开始,该参数会随着PGA_AGGREGATE_TARGET参数的调整而自动调整,从而提供更好的性能。
NAME VALUE PDESC
-------------------- --------------- ------------------------------------------------------------
_pga_max_size 209715200 Maximum size of the PGA memory for one process
PGA的调整建议
伴随着自动PGA调整功能的引入,Oracle同时引入相应的动态性能视图用于优化建议。PGA的优化建议通过v$pga_target_advice和v$pga_target__histogram提供。
v$pga_target_advic视图通过不同PGA设置进行评估,给出在不同设置下的PGA命中率和OverAlloc信息。
SQL> select PGA_TARGET_FOR_ESTIMATE/1024/1024 PGA_EST_MB,
2 PGA_TARGET_FACTOR,ESTD_PGA_CACHE_HIT_PERCENTAGE,
3 ESTD_OVERALLOC_COUNT
4 from v$pga_target_advice;
PGA_EST_MB PGA_TARGET_FACTOR ESTD_PGA_CACHE_HIT_PERCENTAGE ESTD_OVERALLOC_COUNT
---------- ----------------- ----------------------------- --------------------
11.25 .125 96 4
22.5 .25 96 4
45 .5 100 0
67.5 .75 100 0
90 1 100 0
108 1.2 100 0
v$PGA_TARGET_ADVICE_HISTOGRAM视图可以通过对不同工作区大小的采样评估提供统计信息供分析使用。
PGA的转储
对于PGA的进一步研究可以通过转储PGA内存结构来实现,Oracle提供如下命令用于将PGA转储到跟踪文件:
Alter session set events ‘immediate trace name heapdump level n’;
Level 1 PGA汇总信息
Level 2 SGA汇总信息
Level 4 UGA汇总信息
Level 8 当前调用的汇总信息(CGA)
Level 16 用户调用的汇总信息(CGA)
Level 32 Large Pool的汇总信息
Level 1025 PGA详细信息
Level 2050 SGA详细信息
Level 5000 UGA详细信息
Level 8200 当前调用的详细信息
Level 16400 用户调用的详细信息
Level 32800 Large Pool的详细信息
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25069245/viewspace-697943/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/25069245/viewspace-697943/