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)的情 。可以把信号量视为操作系统级的用于管理共享内存的钥匙,每个进程需要有一把,一个信号量集就是一组钥匙,这组钥匙可以打开共同一个共享内存段上的锁。当一个进程需要从共享内存段中获取共享数据时,使用它自己的钥匙打开锁,进入后,再反