allaboutOraclememory-Oracle的内存管理(三)

2014-11-24 16:56:09 · 作者: · 浏览: 7
d pool的空闲列表中,因此能够立即被分配。但是,却包含在视图V$SGASTAT的free memory的统计数据中。

SQL> select * from v$sgastat
  2  where pool = 'shared pool'
  3  and name = 'free memory';
POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  free memory                  18334468

而spare free memory可以用以下方式查出:

select
  avg(v.value)  shared_pool_size,
  greatest(avg(s.ksmsslen) - sum(p.ksmchsiz), 0)  spare_free,
  to_char(
    100 * greatest(avg(s.ksmsslen) - sum(p.ksmchsiz), 0) / avg(v.value),
    '99999'
  ) || '%' wastage
from
  sys.x$ksmss s,
  sys.x$ksmsp p,
  sys.v$parameter v
where
  s.inst_id = userenv('Instance') and
  p.inst_id = userenv('Instance') and
  p.ksmchcom = 'free memory' and
  s.ksmssnam = 'free memory' and
  v.name = 'shared_pool_size';
 

注意:如果10g中用了SGA内存自动管理。以上语句可能无法查出。

当需要时,少量的空闲内存chunk会被释放到shared pool中。除非所有这些少量空闲内存被耗尽了,否则不会报4031错误。如果实例在负载高峰运行了一段时期之后还有大量的少量空闲内存,这就说明sharedpool太大了。

而未pin住的、可重建(unpinned recreatable)的chuck被维护在两个分别用于周期性chunk和短期chunk的LRU链表中。这两个LRU链表的长度可以通过表X$KGHLU查到,同时还能查到被flush的chunk数、由于pin和unpin而加到和从LRU链表中移出的chunk数。X$KGHLU还能显示LRU链表没有被成功flush的次数,以及最近一次这样的请求失败的请求大小。

SQL> column kghlurcr heading "RECURRENT|CHUNKS"
SQL> column kghlutrn heading "TRANSIENT|CHUNKS"
SQL> column kghlufsh heading "FLUSHED|CHUNKS"
SQL> column kghluops heading "PINS AND|RELEASES"
SQL> column kghlunfu heading "ORA-4031|ERRORS"
SQL> column kghlunfs heading "LAST ERROR|SIZE"
SQL> select
  2  kghlurcr "RECURRENT_CHUNKS",
  3  kghlutrn "TRANSIENT_CHUNKS",
  4  kghlufsh "FLUSHED_CHUNKS",
  5  kghluops "PINS AND_RELEASES",
  6  kghlunfu "ORA-4031_ERRORS",
  7  kghlunfs "LAST ERROR_SIZE"
  8  from
  9  sys.x$kghlu
 10  where
 11  inst_id = userenv('Instance');
RECURRENT_CHUNKS TRANSIENT_CHUNKS FLUSHED_CHUNKS PINS AND_RELEASES ORA-4031_ERRORS LAST ERROR_SIZE
---------------- ---------------- -------------- ----------------- --------------- ---------------
             327              368              0              7965               0               0
             865              963           2960            102138               0               0
            1473             5657             96             20546               1             540
               0                0              0                 0               0               0

如果短期链表的长度大于周期链表的长度3倍以上,说明SharedPool太大,如果chunk flash对LRU 操作的比例大于1/20,则说明Shared Pool可能太小。

2.3.Oracle在UNIX下的内存管理

在UNIX下,Oracle是以多进程的方式运行的。除了几个后台进程外,Oracle为每个连接起一个进程(进程名称中,LOCAL = NO)。而UNIX下的内存分为两类,一种叫共享内存,即可以被多个进程共享;还有一种就是私有进程,只能被所分配的进程访问。根据Oracle内存区的不同特性,SGA内存可以被所有会话进程共享,因此是从共享内存中分配的;而PGA是进程私有的,因而是从私有内存中分配的。

2.3.1.共享内存和信号量

在Unix下,Oracle的SGA是保存在共享内存中的(因为共享内存是可以被多个进程共享的,而SGA正是需要能被所有Oracle进程所共享)。因此,系统中必须要有足够的共享内存用于分配SGA。而信号量则是在共享内存被多个进程共享时,防止发生内存冲突的一种锁机制。

UNIX下,对于内存的管理配置,是由许多内核参数控制,在安装使用Oracle时,这些参数一定要配置正确,否则可能导致严重的性能问题,甚至Oracle无法安装、启动。涉及共享内存段和信号量的参数:

参数名称

建议大小(各个平台的Oracle建议值可以去metalink上找)

参数描述

SHMMAX

可以得到的物理内存

(0.5*物理内存)

定义了单个共享内存段能分配的最大数.

SHMMAX必须足够大,以在一个共享内存段中能足够分配Oracle的SGA空间.这个参数设置过低会导致创建多个共享内存段,这会导致Oracle性能降低.

SHMMIN

定义了单个共享内存段能分配的最小数.

SHMMNI

512

定义了整个系统共享内存段的最大数。

NPROC

4096

系统的进程总数

SHMSEG

32

定义了一个进程能获取的共享内存段的最大数.

SEMMNS

(NPROC * 2) * 2

设置系统中的信号数.

SEMMNS的默认值是128

SEMMNI

(NPROC * 2)

定义了系统中信号集的最大数

SEMMSL

与Oracle中参数processes大小相同

一个信号集中的信号最大数

SEMMAP

((NPROC * 2) + 2)

定义了信号映射入口最大数

SEMMNU

(NPROC - 4)

定义了信号回滚结构数

SEMVMX

32768

定义了信号的最大值

信号量(Semaphore):对于每个相关的process都 予一个信号 表示其目前的 态。主要的目地在于确保process间能同步,避免process存取shared data时产生碰撞(collisions)的情 。可以把信号量视为操作系统级的用于管理共享内存的钥匙,每个进程需要有一把,一个信号量集就是一组钥匙,这组钥匙可以打开共同一个共享内存段上的锁。当一个进程需要从共享内存段中获取共享数据时,使用它自己的钥匙打开锁,进入后,再反