我们经常可以听到这样的说法,“在32位的GNU/Linux平台上默认安装的Oracle最大只能使用约1.7GB的SGA”。CALIS联合目录在地区中心部署的整个软硬件环境都是32位,操作系统采用Red Flag Linux DC Server 4.1,数据库软件为Oracle 10g Release 1,数据库需要安装在拥有8GB内存的IBM xSeries 365上。大家一方面担心1.7GB的SGA不足以支撑这么大一个服务,造成性能瓶颈;一方面又担心8GB的物理内存如果只有1.7GB能够被Oracle所使用,造成资源浪费。因此,许多人就想知道,“如何扩展SGA超过SGA最大约1.7GB的限制”?
其实上面提到的说法并不够准确,SGA的最大值既与用户安装Oracle所使用的内核(Kernel)有关,也与用户所安装的Oracle版本有关,同时还与一个内核参数shmmax有重要的关联[1]。需要重点指出的是,shmmax定义单个共享内存段的最大值,它的取值范围区间是[0,4294967295], 单位为byte,4294967295 bytes即4294967296 bytes(4GB)减去1。一般来说,它应该足够大以容下整个SGA,避免SGA使用多个共享内存段造成Oracle性能下降。
Red Flag Linux DC Server 4.1在IBM xSeries 365上默认安装后所使用的内核是2.4.21-9.30AXsmp,该内核采用3:1的比例将虚拟地址空间(Virtual Address Space,VAS)分配给用户进程和内核进程使用,具体的分配方式如下[1]:
1. 0GB-1GB User space - Used for text/code and brk/sbrk allocations (malloc uses brk for small chunks)
2. 1GB-3GB User space - Used for shared libraries, shared memory, and stack; shared memory and malloc use mmap (malloc uses mmap for large chunks)
3. 3GB-4GB Kernel Space - Used for the kernel itself
从这里我们可以看出,用户进程其实只能够使用0GB-3GB的虚拟地址空间,其中用来分配共享库(shared libraries)或者共享内存段(shared memory segment)的的虚拟地址空间为(1GB-3GB)。如果在此内核下采用oranavi命令安装Oracle 10g Release 1,由于shmmax被设置为2147483648(2GB),挂载SGA的起始地址为0x50000000(1.25GB),很明显理论上SGA最大值为1.75GB(3GB-1.25GB)。
如果安装Red Flag Linux DC Server 4.1之后再安装一个hugemem kernel(kernel-hugemem-2.4.21-9.30AX.i686.rpm),用户进程可用的虚拟地址空间则为4GB。在此内核下安装Oracle 10g Release 1,挂载SGA的起始地址为0x50000000,shmmax为2147483648,理论上SGA的最大值为2GB。如果增大shmmax(比如320864256),则理论上SGA最大值为2.75GB。
而对于Oracle 10g Release 2,由于挂载SGA的起始地址为0x20000000(0.5GB),如果增大shmmax(比如为4294967295),则理论上SGA最大值在smp内核下为2.5GB,在hugemem内核下为3.5GB。
以上三个段落的叙述,我们应该能够明白,在32位GNU/Linux平台上,SGA的最大值与内核版本、Oracle版本以及内核参数shmmax都是相关的。在拥有8GB内存的IBM xSeries 365上安装Red Flag Linux DC Server 4.1,使用默认内核,再使用oranavi命令安装Oracle 10g Release 1后,我们也应该能够想到以下三种扩展SGA的方法:
1. 安装并使用hugemem内核
2. 减小挂载SGA的起始地址[2]
3. 升级到Oracle 10g Release 2
由于CALIS联合目录项目在默认的内核以及Oracle 10g Release 1下经过长期的测试表现稳定,因此并不推荐第1和第3种方法。至于第2种方法,因为增大SGA势必将减少其它用户进程可使用的内存,这可能会造成这个系统性能的下降。
事实上,如果使用hugemem内核,尽管用户进程可用的虚拟地址空间为4GB以及shmmax的最大值为4294967295,我们仍然可以通过使用内存文件系统(in-memory filesystem,比如tmpfs、ramfs以及hugetlbfs)打开Oracle的Very Large Memory (VLM)特性来扩展SGA超过4GB[1],比如6GB。但是这种方法有个不方便的地方是,用户不能够再使用Oracle 10g中的Automatic Shared Memory Management了。
另外,另外一种可能的扩展SGA的方法是减小shmmax,使得SGA使用多个共享内存段[3]。如前所述,这样反而会造成Oracle性能下降。而且,再实际试验过程中,我们设置shmmax为268435456(256MB)时并没有能够以超过1632MB大小的SGA成功启动Oracle 10g Release 1。
总结来说,对于CALIS联合目录系统,我们并不推荐扩展SGA。我们认为,不如放弃扩展SGA,转而调整PGA。经过长期测试,我们发现使用1632MB的SGA以及868MB的PGA,足以满足CALIS联合目录系统的高效率运行。但是,如果大家有其它实际应用需要扩展SGA,希望以上的讨论可以提供一些有用的参考。由于缺乏充分的实践,也希望大家能够指出文中的错误。