我们一般在Linux 上安装设置Oracle 数据库或者在更换或升级硬件的时候都需要配置Linux 系统的核心参数,然后才是调整Oracle 系统参数 。
具体这些参数的实质意义是什么,为什么要做调整,如何合理调整? 带着这些问题我们做以下的一些分析以及测试。
注意: 以下的一些测试可能只适用于Linux 系统,且测试Linux 系统为64Bit,32Bit Linux 系统可能有不一样 。
测试环境: Linux AS 4.0 U5 64Bit
核心版本: 2.6.9-55.ELsmp #1 SMP x86_64
1. Linux 系统下的核心参数:
[root@ECSDB etc]# cat sysctl.conf 或者到 /proc/sys/kernel 下查看。
kernel.shmall = 2097152
kernel.shmmax = 8405194752
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_default = 262144
net.core.rmem_max = 262144
net.core.wmem_default = 262144
net.core.wmem_max = 262144
----- 小技巧: 修改 /etc/sysctl.conf 文件之后立刻生效命令 # sysctl -p
2. Linux 下核心参数调整
总之,一般设置shmmax >=SGA (32Bit 系统是否支持到1.7G 以上SGA 需要注意) 。如果是64Bit 的Linux 操作系统,shmmax 设置为大于SGA_MAX_SIZE 即可。 (仅供参考)
Ipcs
kernel.shmall ----
kernel.shmall 参数是控制共享内存页数 。Linux 共享内存页大小为4KB, 共享内存段的大小都是共享内存页大小的整数倍。一个共享内存段的最大大小是16G,那么需要共享内存页数是 16GB/4KB=16777216KB/4KB=4194304 (页),也就是64Bit 系统下16GB 物理内存,设置 kernel.shmall = 4194304 才符合要求(几乎是原来设置2097152的两倍)。这时可以将shmmax 参数调整到 16G 了,同时可以修改SGA_MAX_SIZE 和SGA_TARGET 为 12G(您想设置的SGA 最大大小,当然也可以是2G~14G 等,还要协调PGA参数及OS 等其他内存使用,不能设置太满,比如16G)。
kernel.shmmni ----
shmmni 内核参数是共享内存段的最大数量(注意这个参数不是 shmmin,是shmmni, shmmin 表示内存段最小大小 ) 。shmmni 缺省值 4096 ,一般肯定是够用了 。
3. Oracle 下需要做调整的参数
SGA_MAX_SIZE
SGA_TARGET
DB_CACHE_SIZE
SGA_MAX_SZIE 为实例允许使用的sga 上限,一个静态参数,是不能动态修改的SGA_TARGET 为10g 推出的sga 自动管理的参数,动态参数,可以动态修改.sga_max_size 与 SGA 各组件大小的关系设置的 sga_max_size 小于实际的SGA 中各个pool 的尺寸总和的大小,那么sga_max_size 的值会被oracle 自动以实际的SGA 的总尺寸代替。如果不设置sga_max_size ,oracle 会自动的以实际的SGA 的总尺寸来设置sga_max_size 的值。设置 sga_max_size 的值为大于SGA 中各个pool 的尺寸总和的值:但是sga_max_size 的值相对于所有可用的物理内存来说,是一个合理的值。sga_max_size的实际的值和pfile 中的sga_max_size 指定的值是一样的。
在Oracle 10g 中引入了一个非常重要的参数:SGA_TARGET,这也是Oracle 10g的一个新特性。自动共享内存管理(Automatic Shared Memory Management ASMM),控制这一特性的,就仅仅是这个参数SGA_TARGE。设置这个参数后,你就不需要为每个内存区来指定大小了。SGA_TARGET 指定了SGA 可以使用的最大内存大小,而SGA 中各个内存的大小由Oracle 自行控制,不需要人为指定。Oracle 可以随时调节各个区域的大小,使之达到系统性能最佳状态的个最合理大小,并且控制他们之和在SGA_TARGET 指定的值之内。一旦给SGA_TARGET 指定值后(默认为0,即没有启动ASMM),就自动启动了ASMM特性。
10g 下设置 SGA_TARGET 之后启动ASSM 特性之后, 只有以下的这些区的内存大小动态
共享起来:
* Buffer cache (DB_CACHE_SIZE)
* Shared pool (SHARED_POOL_SIZE)
* Large pool (LARGE_POOL_SIZE)
* Java pool (JAVA_POOL_SIZE)
* Streams pool (STREAMS_POOL_SIZE)
而SGA 中的其他区域的内存大小仍然是固定不共享的。它的含义和SGA_MAX_SIZE 的一样,也表示SGA 最大的大小,于是它也就有了一个限制,那就是它的大小不能大于SGA_MAX_SIZE 的大小。Oracle10g 下, SGA_MAX_SIZE 仍然表示SGA 的大小的上限值,而SGA_TARGET 是SGA 的所有组件的大小的最大值之和,即当SGA_TARGET< SGA_MAX_SIZE 的时候,oracle就会忽略SGA_MAX_SIZE 的值,SGA_TARGET 也就成了SGA 的在此实例中的上限制,它能动态改变大小,但是不能够大于SGA_MAX_SIZE 的值。
有人曾经做过试验,在某些版本中(可能在我的版本之后的版本),当SGA_TARGET< SGA_MAX_SIZE 时,实例重启以后SGA_MAX_SIZE 就变成SGA_TARGET 的大小了。
在11g 中,这个SGA_TARGET 只能设置是等于SGA_MAX_SIZE 的大小了,设置比它小,oracle 会自动帮你调整,设置比它大,那还是出错。现在可以自己想想,oracle对SGA_TARGET 的大小处理在往正确的简单的方向前进中。
SGA_TARGET 带来一个重要的好处就是,能使SGA 的利用率达到最佳,从而节省内存成本。因为ASMM 启动后,Oracle 会自动根据需要调整各个区域的大小,大大减少了某些区域内存紧张,而某些区域又有内存空闲的矛盾情况出现。