深入探讨Oracle内存分配管理(下)

原创|其它|编辑:郝浩|2010-01-14 09:49:13.000|阅读 601 次

概述:对于 oracle 的内存的管理,截止到9iR2,都是相当重要的环节,管理不善,将可能给数据库带来严重的性能问题。下面我们将一步一步就内存管理的各个方面进行探讨。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

  假如把’TOM’ 和 ‘JERRY’ 换做变量V,那就是使用了bind var,我们可以认为是同样的SQL 从而能很好地共享。共享SQL 本来就是shared_pool_size 这部分内存存在的本意,oracle的目的也在于此,而我们不使用bind var 就是违背了oracle 的初衷,这样将给我们的系统带来严重的问题。当然,如果通过在操作系统监控,没有发现严重的cpu问题,我们如果发现该共享池命中率不高可以适当的增加shred_pool_size。但是通常我们不主张这部分内存超过800M(特殊情况下可以更大)。

  事实上,可能的话我们甚至要想办法避免软分析,这在不同的程序语言中实现方式有差异。我们也可能通过设置session_cached_cursors 参数来获得帮助(这将增大PGA)。

  Data buffer

  现在我们来谈数据缓冲区,在确定了SGA 的大小并分配完了前面部分的内存后,其余的,都分配给这部分内存。通常,在允许的情况下,我们都尝试使得这部分内存更大。这部分内存的作用主要是缓存DB BLOCK,减少甚至避免从磁盘上获取数据,在8i中通常是由db_block_buffers*db_block_size 来决定大小的。如果我们设置了buffer_pool_keep 和buffer_pool_recycle,则应该加上后面这两部分内存的大小。

  9i下参数的变化

  Oracle的版本的更新,总是伴随着参数的变化,并且越来越趋向于使得参数的设置更简单,因为复杂的参数设置使得DBA们经常焦头烂额。关于内存这部分的变化,我们可以考察下面的参数。事实上在9i中数据库本身可以给出一组适合当前运行系统的SGA相关部分的参数调整值(参考V$DB_CACHE_ADVICE、V$SHARED_POOL_ADVICE),关于PGA也有相关视图V$PGA_TARGET_ADVICE 等。

  Data buffer

  9i 中保留了8i中的参数,如设置了新的参数,则忽略旧的参数。9i中用db_cache_size来取代db_block_buffers , 用db_keep_cache_size 取代buffer_pool_keep, 用db_recycle_cache_size 取代buffer_pool_recycle;这里要注意9i 中设置的是实际的缓存大小而不再是块的数量。另外9i新增加了db_nk_cache_size,这是为了支持在同一个数据库中使用不同的块大小而设置的。对于不同的表空间,可以定义不同的数据块的大小,而缓冲区的定义则依靠该参数的支持。其中n 可以为2、4、6、8、16 等不同的值。在这里顺便提及的一个参数就是db_block_lru_latches,该参数在9i中已经成为了保留参数,不推荐手工设置。

  PGA

  在9i 里面这部分也有了很大的变化。在独立模式下,9i已经不再主张使用原来的UGA相关的参数设置,而代之以新的参数。假如workarea_size_policy=AUTO(缺省),则所有的会话的UGA 共用一大块内存,该内存由pga_aggregate_target 设置。在我们根据前面介绍的方法评估了所有进程可能使用的最大PGA 内存之后,我们可以通过在初始化参数中设置这个参数,从而不再关心其他”*_area_size” 参数。

  SGA_MAX_SIZE

  在9i中若设置了SGA_MAX_SIZE,则在总和小于等于这个值内,可以动态的调整数据缓冲区和共享池的大小


  SQL> show parameters sga_max_size
  NAME TYPE VALUE
  ------------------------------------ ------- -------------
  sga_max_size unknown 193752940
  SQL> alter system set db_cache_size = 30000000;
  System altered.
  SQL> alter system set shared_pool_size = 20480000;
  System altered.

  Lock_SGA = TRUE 的问题

  由于几乎所有的操作系统都支持虚拟内存,所以即使我们使用的内存小于物理内存,也

  不能避免操作系统将SGA 换到虚拟内存(SWAP)。所以我们可以尝试使得SGA 锁定在物理内存中不被换到虚拟内存中,这样减少页面的换入和换出,从而提高性能。但在这里遗憾的是,windows 是无法避免这种情况的。下面我们来参考在不同的几个系统下怎么实现lock_sga

  AIX 5L(AIX 4.3.3 以上)

  logon aix as root

  cd /usr/samples/kernel

  ./vmtune (信息如下) v_pingshm已经是1

  ./vmtune -S 1

  然后oracle用户修改initSID.ora 中 lock_sga = true

  重新启动数据库

  HP UNIX

  Root身份登陆

  Create the file "/etc/privgroup": vi /etc/privgroup

  Add line "dba MLOCK" to file

  As root, run the command "/etc/setprivgrp -f /etc/privgroup":

  $/etc/setprivgrp -f /etc/privgroup

  oracle用户修改initSID.ora中lock_sga=true

  重新启动数据库

  SOLARIS (solaris2.6以上)

  8i版本以上数据库默认使用隐藏参数 use_ism = true ,自动锁定SGA于内存中,不用设置lock_sga, 如果设置 lock_sga =true 使用非 root 用户启动数据库将返回错误。

  WINDOWS

  不能设置lock_sga=true,可以通过设置pre_page_sga=true,使得数据库启动的时候就把所有内存页装载,这样可能起到一定的作用。

  关于内存参数的调整

  关于参数调整,是oracle的复杂性的一个具体体现。通常来讲,我们更倾向于让客户做statspack 报告,然后告诉我们os 监控的状况,在这些的信息的基础上,再向客户索取具体

  的详细信息以诊断问题的所在。系统的调整,现在我们通常采用从等待事件入手的方法。因为一个系统感觉到慢,必然是在某个环节上出现等待,那么我们从等待最多的事件入手逐步诊断并解决问题。

  对于内存的调整,相对来说简单一些,我们首先可以针对数据缓冲区的大小来看。首先观察命中率。

  数据缓冲区命中率


  SQL> select value from v$sysstat where name ='physical reads';
  VALUE
  ----------
  14764
  SQL> select value from v$sysstat where name ='physical reads direct';
  VALUE
  ----------
  50
  SQL> select value from v$sysstat where name ='physical reads direct (lob)';
  VALUE
  ----------
  0
  SQL> select value from v$sysstat where name ='consistent gets';
  VALUE
  ----------
  167763
  SQL> select value from v$sysstat where name = 'db block gets';
  VALUE
  ----------
  14305

  这里命中率的计算应该是

  令 x = physical reads direct + physical reads direct (lob)

  命中率 =100 - ( physical reads - x) / (consistent gets + db block gets - x)*100

  通常如果发现命中率低于90%,则应该调整应用可可以考虑是否增大数据缓冲区共享池的命中率


  SQL> select sum(pinhits-reloads)/sum(pins)*100 "hit radio" from v$librarycache;
  hit radio
  ----------
  99.809291

  假如共享池的命中率低于95%,就要考虑调整应用(通常是没使用bind var )或者增加内存。

  关于排序部分


  SQL> select name,value from v$sysstat where name like '%sort%';
  NAME VALUE
  ---------------------------------------------------------------- -------
  sorts (memory) 67935
  sorts (disk) 1
  sorts (rows) 7070

  假如我们发现sorts (disk)/ (sorts (memory)+ sorts (disk))的比例过高,则通常意味着sort_area_size 部分内存较小,可考虑调整相应的参数。

  关于log_buffer


  SQL> select name,value from v$sysstat
  2 where name in('redo entries','redo buffer allocation retries');
  NAME VALUE
  ----------------------- -------------------------------------
  redo entries 2325719
  redo buffer allocation retries 10

  假如redo buffer allocation retries/ redo entries 的比例超过1%我们就可以考虑增大log_buffer

  通常来说,内存的调整的焦点就集中在这几个方面,更多更详细的内容,建议从statspack入手来一步一步调整。最后关于内存的调整,再强调这一点,一定要结合操作系统来衡量,任何理论都必须要实践来检验。在操作系统中观察page in/out 状况,发现问题严重,应该考虑调小SGA。

  32bit 和64bit 的问题

  对于oracle 来说,存在着32bit与64bit的问题。这个问题影响到的主要是SGA的大小。在32bit的数据库下,通常oracle只能使用不超过1.7G的内存,即使我们拥有12G的内存,但是我们却只能使用1.7G,这是一个莫大的遗憾。假如我们安装64bit的数据库,我们就可以使用很大的内存,我们几乎不可能达到上限。但是64bit 的数据库必须安装在64bit 的操作系统上,可惜目前windows 上只能安装32bit的数据库,我们通过下面的方式可以查看数据库是32bit 还是64bit:


  SQL> select * from v$version;
  BANNER
  ----------------------------------------------------------------
  Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
  PL/SQL Release 8.1.7.0.0 - Production
  CORE 8.1.7.0.0 Production
  TNS for 32-bit Windows: Version 8.1.7.0.0 - Production
  NLSRTL Version 3.4.1.0.0 - Production

  但是在特定的操作系统下,可能提供了一定的手段,使得我们可以使用超过1.7G 的内存,达到2G 以上甚至更多。在这里我们针对不同的平台下的具体实现方式做一个总结。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP