您的位置:首页 >> 数据库 >> Oracle >> 正文
Oracle RSS
 

Oracle 10g 可以自动共享内存管理

http://www.rdxx.com 06年05月03日 16:15 网络 我要投稿

 
  是不是很难准确地分配
配到最需要的地方去成为可
不同的池所需的内存数?自动共
能。
享内存管理特性使得自动将内存分


  无论您是一个刚入门的
的错误:
DBA 还是一个经验丰富的 DBA

,您肯定至少看到过一次类似以下


  ORA-04031:unable to
allocate 2216 bytes of share
d memory ("shared pool"... ...

  或者这种错误:                                                               
  ORA-04031:unable to allocate XXX
X bytes of shared memory
  ("large pool","unknown object","
session heap","frame")


  或者可能这种错误:                                                           
  ORA-04031:unable to
allocate bytes of shared mem
ory ("shared pool",
  "unknown object","joxlod:init h"
, "JOX:ioc_allocate_pal")

  第一种错误的原因很明
原因可能不是池本身的大小
的一个主题;但目前让我们
池的空间不足。
显:分配给共享池的内存不足以
,而是未使用绑定变量导致的过
把重点放在手头的问题上。)其

满足用户请求。(在某些情况下,
多分析造成的碎片,这是我很喜欢
它的错误分别来自大型池和 Java


  您需要解决这些错误情
问题是如何在 Oracle 例程
况,而不作任何与应用程序相关
所需的所有池之间划分可用的内
的修改。那么有哪些方案可选呢?
存。

  馅饼怎么分?

  正如您所了解的,一个
冲高速缓存、共享池、Java
占据了固定的内存数;它们
Oracle 例程的系统全局区域 (
池、大型池和重做日志缓冲)
的大小由 DBA 在初始化参数文
SGA) 包含几个内存区域(包括缓
。这些池在操作系统的内存空间中
件中指定。

  这四个池(数据库块缓冲高速缓存、
的空间。(与其它区域相比,重做日志缓
)作为 DBA,您必须确保它们各自的内存
共享池、Java 池和大型池)几乎占据了 SGA 中所有
冲没有占据多少空间,对我们这里的讨论无关紧要。
分配是充足的。

  假定您决定了这些池的值分别是 2GB
数据库例程规定池的大小。
、1GB、1GB 和 1GB。您将设置以下初始化参数来为

  db_cache_size = 2g                                          
  shared_pool_size = 1g                                    
  large_pool_size = 1g                                      
  java_pool_size = 1g                                        

  现在,仔细看一下这些参数。坦白讲,这些值是否准确?                           

  我相信您一定会有疑虑
赖于数据库内部的处理,而
。在实际中,没有人能够为这些
处理的特性随时在变化。
池指定确切的内存数 — 它们太依


  下面是一个示例场景。
速缓存分配的专用内存比为
用户放开了一些非常大的全
线修改内存分配的功能,但
些内存:
假定您有一个典型的、大部分属
纯 OLTP 数据库(现在已经很少
表扫描,以创建当天的结束报表
由于提供的总物理内存有限,您

于 OLTP 的数据库,并且为缓冲高
见了)分配的要少。有一天,您的
。Oracle9i 数据库为您提供了在
决定从大型池和 Java 池中取出一

  alter system set db_cache_size =
3g scope=memory;
  alter system set lar
ge_pool_size = 512m scope=me
mory;
  alter system set jav
a_pool_size = 512m scope=mem
ory;

  这个解决方案能够很好地工作一段时
开始了,大型池将立即出现内存不足。同
池,以挽救这种局面。
间,但是接着夜间的 RMAN 作业(它们使用大型池)
样,您从数据库高速缓存中取出一些内存来补充大型


  RMAN 作业完成,然后
池相关的错误。因此,您(
求:
启动一个广泛使用 Java 的批处
再次)重新分配池,以满足 Jav

理程序,接着您开始看到与 Java
a 池和数据库高速缓存上的内存需

  alter system set db_cache_size =
2G scope=memory;
  alter system set lar
ge_pool_size = 512M scope=me
mory;
  alter system set jav
a_pool_size = 1.5G scope=mem
ory;

  第二天早上,OLTP 作业恢复在线,这个循环又完全重复!                     

  解决这种恶性循环的一种替代方法是
分配的总的 SGA 可能超出可用的内存 —
和分页的风险。人工重新分配的方法(虽
永久设置每个池的最大需求。不过,这么做的话,您
从而在为每个池分配的内存数不足时,将增加交换
然不实际)目前看起来很不错。

  另一种替代方法是将值
性能将受到影响。
设为可接受的最小值。不过,当

需求增长且内存不能完全满足时,


  注意在所有这些示例中,分配给 SGA
的需求进行修改。如果 RDBMS 将自动探
是很好吗?
的总内存保持不变,而池之间的内存分配根据即时
测来自用户的需求并相应地重新分布内存分配,那不


  Oracle 数据库 10g 中的自动共享内
SGA 的总大小,然后设置一个名称为 SGA
SGA 内部的各个池将根据工作负载动态地
参数的一个非零值。
存管理特性正好能够实现这一目的。您可以决定
_TARGET 的参数,这个参数决定 SGA 的总大小。
进行配置。实现自动内存分配仅仅需要 SGA_TARGET


  设置自动共享内存管理

  让我们看看该特性是如
了多少内存来估计这个值。
何工作的。首先,确定 SGA 的

总大小。您可以通过确定现在分配

  SQL> select sum(value)/1024/1024 from v$sga;


  SUM(VALUE)/1024/1024                                      
  --------------------                                      
           500                                                      

  此时 SGA 的当前总大
执行语句:
小近似为 500MB,并且这个值将

变为 SGA_TARGET 的值。接下来,

  alter system set sga_target = 50
0M scope=both;

  这种方法不需要为各个池设置不同值
部删除它们。
;因而,您将需要在参数文件中使它们的值为零或全

  shared_pool_size = 0                                      
  large_pool_size = 0                                        
  java_pool_size = 0                                          
  db_cache_size = 0                                         

  再循环数据库,使这些值生效。                                                 

  这个人工过程还可以通
"Administration" 选项卡
显示标记为 "Enable" 的按
共享内存管理特性。企业管
过 EntERPrise Manager 10g 实
,然后选择 "Memory Parameter
钮,以及所有人工配置的池的值
理器将完成剩下的工作。
施。从数据库主页中,选择
s"。对于人工配置的内存参数,将
。单击 "Enable" 按钮,启用自动


  在配置了自动内存分配之后,您可以利用以下命令检查它们的大小:                 
  SQL> select current_size from v$buffer_pool;


  CURRENT_SIZE                                                      
  ------------                                                      
       340                                                              

  SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool;


  POOL       MBYTES                                            
  ------------ ----------                                
  java pool       4                                            
  large pool      4                                            
  shared pool     148                                        

  正如您所看到的,所有
缓冲高速缓存大小是 340MB
总的大小为 (340+4+4+148=
的池都从 500MB 的总目标大小
,Java 池是 4MB,大型池是 4M
) 496MB,近似与 500MB 的目标
中自动进行分配。(参见图 1。)
B,共享池是 148MB。它们合起来
SGA 的大小相同。
  


  
图 1:池的初始分配


  现在假定提供给 Oracl
SGA 的大小。我们可以通过
e 的主机内存从 500MB 减少为
减小目标 SGA 大小来反映这种
300MB,这意味着我们必须减少总
变化。


  alter system set sga
_target = 300M scope=both;

  现在查看各个池,我们可以看到:                                               
  SQL> select current_size from v$buffer_pool;


  CURRENT_SIZE                                                      
  ------------                                                      
       244                                                              

  SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool;


  POOL       MBYTES                                            
  ------------ ----------                                
  java pool       4                                            
  large pool      4                                            
  shared pool     44                                          

  占用的总大小是 240+4
SGA_TARGET 改变时,如何
+4+44 = 296MB,接近于目标的
自动重新分配池。
300MB。注意如图 2 所示,当

  


  
图 2:在将 SGA 大小减少到 300MB 之后重新分配池


  这些池的大小是动态的。池将根据工
个池的扩展。这种扩展或缩小自动发生,
们暂时返回到那个场景,假定在初始分配
大型池将从 4MB 扩展到 40MB,以容纳需
库块缓冲将缩小,如图 3 所示。
作负载扩展,以容纳需求的增长,或缩小以容纳另一
无需 DBA 的干预,这与本文开头的示例不同。让我
后,RMAN 作业启动,指示需要一个更大的大型池,
求。这个额外的 36MB 将从数据库缓冲中划出,数据

  


  
图 3:在对大型池的需求增长之后经过重新分配的池


  池的大小变化基于系统
根据需求的增长自动调整。
此不存在使内存需求的增长
SGA_TARGET 增加至绝对最
上的工作负载,因此不需要为最
此外,SGA 的总大小始终在由 S
比例失调(这将导致分页和交换
大值,这个绝对最大值是通过调
坏的情况调整池的大小 — 它们将
GA_TARGET 指定的最大值之内,因
)的风险。您可以动态地将
整参数 SGA_MAX_SIZE 指定的。

  哪些池不受影响?

  SGA 中的一些池不受动
非标准块大小的缓冲池,以
个块大小为 8K,而您想要
。它们的大小将保持不变;
KEEP 池和 RECYCLE 池时,
管工作负载如何,在参数 l
定义一种新的池:流池 (st
受自动内存调整的影响。)
态大小调整的影响,但是必须显
及 KEEP 池或 RECYCLE 池的非
配置 2K、4K、16K 和 32K 块大
它们将不会根据负载缩小或扩展
您应当考虑这个因素。此外,日
og_buffer 中设定的值是不变的
ream pool),它用参数 streams

式指定这些池。其中值得注意的是
默认块大小。如果您的数据库有一
小的池,那么您必须手动设置它们
。当使用多种大小的缓冲池、
志缓冲不受内存调整的影响 — 不
。( 在 10g 中,还可以在 SGA 中
_pool_size 进行设置。该池也不


  这就产生了一个有趣的问题。如果您
池,那么该怎么办?
需要一个非默认块大小的池,而且想自动管理其它的


  如果您指定了这些非自
的总大小将从 SGA_TARGET
变。例如,假设值看起来像
动调整的参数中的任意一个(如
值中减去,以计算自动调整的参
这样:
db_2k_cache_size),那么它们
数值,以使 SGA 的总大小保持不

  sga_target = 500M                                            
  db_2k_cache_size = 50M                                  

  其余的池参数未设置。50MB 的 2KB
(db_cache_size)、共享池、Java 池和大
自动调整的参数(如 2KB 块大小池)—
调整的部分将重新调整。例如,将 db_2k
动调整的参数剩余 400MB。因此,如图 4
默认缓冲池)自动缩小,以将它们的总大
缓冲池为自动调整的池(如默认块大小缓冲池
型池)保留了 450MB。当以一种方法动态地调整不可
—这种方法将影响到可自动调整部分的大小,可自动
_cache_size 的值从 50MB 提高到 100MB 只为可自
所示,可调整的池(如共享池、大型池、Java 池和
小从 450MB 减少到 400MB。
  


  
图 4:配置非自动缓冲参数的效果


  但如果您有足够的可用
的话,您可以通过不指定参
过使用 ALTER SYSTEM 动态
0 时,池的当前值被自动设
内存,或者上述风险可能不是那
数文件中的参数 SGA_TARGET、
地将其修改为 0 来关闭自动大
为它们的参数。
么明显,那应该怎么办?如果这样
通过在文件中将其设为 0,或者通
小调整。当 SGA_TARGET 被设为

  使用 Enterprise Manager                                   

  您还可以使用 Enterpr
"Memory Parameters",这
ise Manager 10g 来处理这些参
将显示一个类似于图 5 中的屏
数。从数据库主页中单击超链接
幕。
  


  
图 5:在 Enterprise Manager 中调整自动共享内存管理


  注意红圈中的项目:数据库在 Autom
小为 564MB — 与在参数 SGA_TARGET 中
Apply 按钮接受这些值;可调整的参数将
atic Shared Memory Management 模式下运行,总大
指定的值相同。您可以在此修改它,然后单击
自动调整。

  为每个池指定一个最小值

  假定您将 SGA_TARGET 设为 600MB,并且各个池已自动分配:     

  池 大小 (MB)                                                           
  缓冲池 404                                                               
  Java 池 4                                                             
  大型池 4                                                                   
  共享池 148                                                               

  看看上述值,您可能推
需要增加。因此,您可能想
16MB。您可以通过在参数文
目的(如下所示)。
断 4MB 的 Java 池和大型池可
确保这些池至少在最初时具有更
件中显式地指定这些池的值或动

能有点不足;这个值在运行时无疑
高的值,比如说,分别为 8MB 和
态使用 ALTER SYSTEM 来实现这一

  alter system set large_pool_size = 16M;
  alter system set java_pool_size = 8M;    

  现在查看这些池,您可以看到:                                                 
  SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool;


  POOL       MBYTES                                            
  ------------ ----------                                
  java pool       8                                            
  large pool      16                                          
  shared pool     148                                        

  SQL> select current_size from v$buffer_pool;


  CURRENT_SIZE                                                      
  ------------                                                      
       388                                                              

  池的重新分配显示如下:                                                        

  池 大小 (MB)                                                           
  缓冲池 388                                                               
  Java 池 8                                                             
  大型池 16                                                                 
  共享池 148                                                               

  注意 Java 池和大型池是如何分别被
SGA 保持在 600MB 以下,缓冲池已从 40
存管理控制 — 它们的大小将根据需求缩
限;它们将永远不会缩小到低于这个界限
重新配置为 8MB 和 16MB,并且注意为了使总的
4MB 减少为 388MB。当然,这些池仍然由自动共享内
小或扩展。您显式指定的值为池的大小设定了一个下


  结论

  Oracle SGA 中的各种池的内存需求
。Oracle 数据库 10g 中的自动共享内存
地方同时施加一个指定的最大值以防止分
更有效的内存管理还带来了更少的内存需
不是静态的 — 相反,它们根据系统上的需求而变化
管理特性通过动态地将资源重新分配到最需要它们的
页和交换,使得 DBA 能够更有效地管理系统内存。
求,这使得更精简的硬件更加可行。

 
 
打印本文
 
 
  热点搜索
 
 
 



Valid XHTML 1.0 Transitional
Copyright ©2005 - 2008 Rdxx.Com,All Rights Reserved
收藏本页
收藏本站