空间管理 您的位置: LUPA开源社区 » ZTK » 日志

PGA理解

上一篇 / 下一篇  2008-03-04 03:01:05 / 个人分类:Oracle


• 首先声明,我们讲PGA内容的前提是在dedicated servers模式下,所以我们这里讲得PGA的内容包括UGA的内容。另外我感觉这一页的内容实在是很枯燥,没办法,我写这部分的时候就觉得很枯燥,现 在让你体验一下我的感觉。如果实在觉得枯燥,我倒是还有一个办法,就是可以先去看看Oracle concept介绍PGA的章节,了解一下什么叫更枯燥,再回头看本页的内容或许感觉会好一点J

• 我绝对没有嘲讽Oracle官方文档的意思,否则我也不会在PPT的很多角落都写上“如想了解更多,请参考Oracle官方文档 xxxxxx。。。。。。”实际上官方文档永永远远都是对技术人员帮助最大,参考得最多的文档,它们详细,准确,包罗万象,不容置疑,采用最最循规蹈矩的 结构,最最一本正经的英文(从来不开玩笑,连打比方都很少,给人的感觉就像在说:oracle是很严肃的,请注意学习态度),但唯一的一点小小瑕疵就是有 点枯燥J 这也是可以理解的,你见过电视说明书和你开玩笑么?

• PGA分为三个主要的部分,第一部分是Private SQL Area,包括persistent arearun-time area


• Session memory就是包含用户session的信息,比如logon time,session memory也是UGA里的内容。
• Process memory,我在加入Process memory这一条的时候心里还是充满忐忑的,因为尽管我知道这一块内存的存在(这一点可以参考Steve Adams的著作《Oracle8i Internal Services for Waits, Latches, Locks, and Memory》的最后一章),但不管怎么说Oracle得官方文档没有这么一个名词,也没提这块内存(我按照session memory杜撰了这个名词)。在我认为,Process Memory存放的是Process相关的信息,包括process使用的Oracle代码。

• 接下来让我们把时间都用来解释Private SQL Area,这部分内存其实也是属于UGA的。

Private SQL Area分为两部分:
persistent area 当open 一个cursor时候persistent area内存被创建,当cursor被close的时候persistent area被回收。所以persistent area就是用来存储cursor需要的内存,包括绑定变量(还有别的么?Oracle文档就举了这么一个例子,所以我就知道这么一个)
大家可以看一下以下两个SQL有什么不同?
select * from table where name=‘Li, xinyu';
select * from table where name= :b1;第二条使用了绑定变量,使用绑定变量的好处就是可以最大限度的共享SQL和执行计划。
这里有必要再解释的一个概念是cursor,cursor在Oracle里也算是个历史悠久概念,但是如果去读Oracle关于cursor的定义,我不清楚到底有多少人能够理解cursor到底是什么:
A cursor is a handle or name for a private SQL area.
其实如果了解PL/SQL,就会知道PL/SQL里的cursor 为程序提供了从数据库中选择多行数据 ,然后对每行数据单独进行处理的方法 ,它为Oracle提供了一种指示和控制SQL处理的各个阶段的方法 。
在PL/SQL 里我们可以明确地指定cursor的open, fetch, close,这是EXPLICIT Cursor,其实不仅仅对PL/SQL,我们执行任何SQL语句都要有一种方法来控制SQL的处理的各个阶段,这个方法就是cursor。我们知道执行 一个SQL,要Parse,要execute,还有可能fetch,但在做这些事情之前请务必先做一件事,那就是open 一个cursor。
有一位大师说:SQL=Cursor,其实很有道理。Cursor的生命周期就是整个SQL的生命周期。

run-time area

run-time area是当你的语句在execution的时候被创建,当语句执行完毕或cancel之后被释放。使用run time area得最典型的代表就是sort。
如果我们在执行select name from mytable order by name;这条语句,Oracle做的事情大致上包括:
• 对SQL语句做parse(解析)并生成执行计划。(如果这个语句以前没有被执行过)
• 检查buffer cache,如果找不到相应的block,把mytable的block从disk读到buffer cache。
• 这时候我们的query可以在buffer cache中读到mytable的数据,然后干什么?
然后就是在PGA里(确切地说, run-time area )对mytable的行进行sort(排序)并最终返回结果。
• 类似于sort,以下操作需要的内存也使用run-time area
• Sort-based operators (order by, group-by, rollup, window function)
• Hash-join
• Bitmap merge
• Bitmap create
• 在Oracle里面,我们PGA中用来做以上4种操作的内存成为Work area:
SQL Work Areas
For complex queries (for example, decision-support queries), a big portion of the
runtime area is dedicated to work areas allocated by memory-intensive operators
such as the following:
1. Sort-based operators (order by, group-by, rollup, window function)
2. Hash-join
3. Bitmap merge
4. Bitmap create

• 在9i以前,PGA的管理是手动的,DBA通过设置SORT_AREA_SIZE, HASH_AREA_SIZE, BITMAP_MERGE_AREA_SIZE和CREATE_BITMAP_AREA_SIZE来控制work area的分配,实际上就是为每一个连上来的用户设置一个固定大小的PGA。(怎么样,这些参数是不是有点眼熟?没错,这些参数都是用来控制Work area的,实际上我们PGA的管理不管手动还是自动,都是针对work area的,所以Oracle对PGA的控制和管理其实并不是全方位的,不要以为你可以完全控制PGA)

这 种设置的问题是显而易见的:一个统一的设置,无法适用于复杂的应用。因为一个系统上的用户请求可能千变万化,有的需要很少的PGA,有的则需要很多。如果 我们分配一个较小的PGA给每一个用户,那么好的,那些对PGA需求大的用户就会抱怨他们的请求处理的很慢。如果我们设置一个很大的PGA,同样也有问 题,一是这对于那些PGA需求不大的用户是一种浪费,更重要的是,当系统的并发用户很多的时候,PGA将耗费很多的内存,导致系统内存短缺。
• 为了改善这种情况,Oracle9i引入了自动管理PGA,在自动模式下,我们只需要指定一个整个系统使用PGA的理论上的上限,Oracle自动根据用 户的请求,系统当时的整体压力等因素来决定为每一个用户分配多少内存。这样自动管理PGA在控制系统使用内存总量的同时,尽量满足不同用户的需求。
• 为了使用自动管理PGA,我们需要设置两个初始化参数:WORKAREA_SIZE_POLICY=auto 和设置一个PGA的理论上的上限,PGA_AGGREGATE_TARGET
• PGA_AGGREGATE_TARGET从名字上看就知道,它是一个target,即目标值。它和我们前面介绍的SGA_MAX_SIZE不同,不是在Oracle启动的时候预先分配的,而是用户在需要内存的时候,先从操作系统请求相应个内存。
• 既然是一个target,那么在用户对内存需求不大的时候,我们实际使用的PGA小于这个target值,而也有可能在一些我们无法控制的情况下(如用户的并发量很大)我们使用的PGA超过这个target。
• 特别指出一点就是PGA_AGGREGATE_TARGET实际上是work area的一个target,那么对于work area以外的那部分内存(比如PL/SQL code),是不受PGA_AGGREGATE_TARGET控制的。因此PGA_AGGREGATE_TARGET确实在很大程度可以控制PGA的使用 内存总量,但并不是100%保证的。我们将在练习中看到这一点。
• 如果我们设置PGA_AGGREGATE_TARGET=1000M,那么如果有用户需要500M的PGA,Oracle会分配500M给他么?
• 答案是不会的,因为自动管理PGA对每一个单独的work area能够使用的内存设定了一个上限,对于串行操作是min(0.05*PGA_AGGREGATE_TARGET, 100M),对于并行操作是0.3 * PGA_AGGREGATE_TARGET / (number of parallel processes),因为在一个多用户的系统里,我们不可能把大量的内存分配个某一个用户,我们总要为不远的将来的,可预计的用户保留一些内存。
• 由于上面这个原因,尽管在Oracle9i里面自动管理PGA是默认的,并且也是推荐的管理PGA内存的方式,我们还是能够给手动管理PGA找到一点用武 之地。简单来说, Automatic PGA Memory Management非常适用于在多用户系统动态的分配内存,但如果你确定你的系统只被极少的用户使用,而且知道用户对PGA的需求很到,可以采用 Manual PGA Memory Management ,给用户手工分配很大的PGA。但是在其他情况下,我们都是建议使用Automatic PGA Memory Management。
• 另外我们需要了解的一点是, Automatic PGA Memory Management 只适用于dedicated servers,无法在shared servers里使用。

fusnow的博客 转

TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

我的栏目

日历

« 2008-08-30  
     12
3456789
10111213141516
17181920212223
24252627282930
31      

数据统计

  • 访问量: 869
  • 日志数: 5
  • 书签数: 1
  • 建立时间: 2006-11-17
  • 更新时间: 2008-03-26

RSS订阅

Open Toolbar