在设置参数之前呢,我们首先要问自己几个问题
一:物理内存多大
二:操作系统估计需要使用多少内存
三:数据库是使用文件系统还是裸设备(没有创建文件系统的磁盘分区)
四:有多少并发连接
五:应用是OLTP 类型还是OLAP 类型
根据这几个问题的答案,我们可以粗略地为系统估计一下内存设置。那我们现在来逐
个问题地讨论,首先物理内存多大是最容易回答的一个问题,然后操作系统估计使用多少内
存呢?从经验上看,不会太多,通常应该在200M 以内(不包含大量进程PCB)。
接下来我们要探讨一个重要的问题,那就是关于文件系统和裸设备的问题,这往往容
易被我们所忽略。操作系统对于文件系统,使用了大量的buffer 来缓存操作系统块。这样当
数据库获取数据块的时候,虽然SGA 中没有命中,但却实际上可能是从操作系统的文件缓
存中获取的。而假如数据库和操作系统支持异步IO,则实际上当数据库写进程DBWR写磁
盘时,操作系统在文件缓存中标记该块为延迟写,等到真正地写入磁盘之后,操作系统才通
知DBWR写磁盘完成。对于这部分文件缓存,所需要的内存可能比较大,作为保守的估计,
我们应该考虑在 0.2——0.3 倍内存大小。但是如果我们使用的是裸设备,则不考虑这部分
缓存的问题。这样的情况下SGA就有调大的机会。
关于数据库有多少并发连接,这实际上关系到PGA 的大小(MTS 下还有
large_pool_size)。事实上这个问题应该说还跟OLTP 类型或者OLAP 类型相关。对于OLTP
类型oracle 倾向于可使用MTS,对于OLAP 类型使用独立模式,同时OLAP 还可能涉及到大
量的排序操作的查询,这些都影响到我们内存的使用。那么所有的问题综合起来,实际上主
要反映在UGA的大小上。UGA主要包含以下部分内存设置

SQL> show parameters area_size

NAME TYPE VALUE
------------------------------------ ------- -------------
bitmap_merge_area_size integer 1048576
create_bitmap_area_size integer 8388608
hash_area_size integer 131072
sort_area_size integer 65536
SQL>
在这部分内存中我们最关注的通常是sort_area_size,这是当查询需要排序的时候,数据
库会话将使用这部分内存进行排序,当内存大小不足的时候,使用临时表空间进行磁盘排序。
由于磁盘排序效率和内存排序效率相差好几个数量级,所以这个参数的设置很重要。这四个
参数都是针对会话进行设置的,是单个会话使用的内存的大小,而不是整个数据库使用的。
偶尔会看见有人误解了这个参数以为是整个数据库使用的大小,这是极其严重的错误。假如
设置了MTS,则UGA被分配在large_pool_size,也就是说放在了共享内存里面,不同进程
(线程)之间可以共享这部分内存。在这个基础上,我们假设数据库存在并发执行server
process 为100 个,根据上面我们4 个参数在oracle8.1.7 下的默认值,我们来计算独立模式
下PGA 的大致大小。由于会话并不会经常使用create_bitmap_area_size 、
bitmap_merge_area_size,所以我们通常不对四个参数求和。在考虑到除这四个参数外会话所
保存的变量、堆栈等信息,我们估计为2M,则200 个进程最大可能使用200M 的PGA。
现在,根据上面这些假定,我们来看SGA 实际能达到多少内存。在1G 的内存的服务
器上,我们能分配给SGA 的内存大约为400—500M。若是2G 的内存,大约可以分到1G
的内存给SGA,8G 的内存可以分到5G的内存给SGA。当然我们这里是以默认的排序部分
内存sort_area_size=64k进行衡量的,假如我们需要调大该参数和hash_area_size等参数,然
后我们应该根据并发的进程的数量,来衡量考虑这个问题。
事实上,通常我们更习惯通过直观的公式化来表达这样的问题:
OS使用内存+SGA+并发执行进程数*(sort_area_size+hash_ara_size+2M) < 0.7*总内存
(公式是死的,系统是活的,实际应用的调整不必框公式,这不过是一个参考建议)
在我们的实际应用中,假如采用的是裸设备,我们可适当的增大SGA(如果需要的话)。
由于目前几乎所有的操作系统都使用虚拟缓存,所以实际上如果就算SGA 设置的比较大也
不会导致错误,而是可能出现频繁的内存页的换入与换出(page in/out)。