曾几何时,网络上流传着给Oracle数据库分配内存的一条法则:把80%的内存分配给Oracle使用,而又将这80%的内存分配80%给Oracle的SGA,剩下的20%分给Oracle的PGA。记得Tom曾说过类似这样的话:如果一个参数的设置对Oracle是最佳的,那么Oracle就会自动地将其设为了默认值。而显然,在内存分配这事上,Oracle的初始设置并不是按这个法则的,那么就是说从某一方面证明这个法则存在问题。
当然大部分DBA不会这样设置内存参数,但是也有不少的人在Oracle的内存分配上存在欠考虑的地方。
首先,我们来看看保留可用内存20%给操作系统是否合适。对于2G内存的服务器(现实中这样的机器不少),20%意味着400M,而通常400M对操作系统来说是不够用的。而对于内存特别多的主机,20%又显得太多。比如下面是一份来自于一台P595的内存情况:
====================================================|==========|=========== Memory Overview | Pages | Megabytes ----------------------------------------------------|----------|----------- Total memory in system | 45875200 | 179200.00 Total memory in use | 34789026 | 135894.63 Free memory | 11086174 | 43305.36 ====================================================|==========|=========== Segment Overview | Pages | Megabytes ----------------------------------------------------|---------|----------- Total segment id mempgs | 32618956 | 127417.79 Total fork tree segment pages | 2074 | 8.10 Total kernel segment id mempgs | 3594452 | 14040.82
这台主机共计179GB物理内存,已使用135G,其中内核占用14G。内核占用的内存不到总内存的10%。
以上的数据以及说明,只是表达这样一个观点,对于操作系统的保留内存,需要根据实际情况预以考虑,这包括了操作系统的内核参数的设置。比如在AIX下的默认设置,client和perm内存可以占用远远超过20%的内存,而HP-UX下的默认设置,File Cache和Buf Cache也可能占用远远超过20%的内存。所以对于这些环境的数据库,一定要注意调整OS的内核参数。对于OS的内存使用,至少保留20%也不失为一种稳妥的做法。
除了操作系统这一块,给Oracle分配内存的时候,还需要注意以下非常重要的几点,这几点经常被人忽略:
- 注意业务高峰期的内存使用:我所维护的一套系统,平时的连接数通常在5000-5500左右,而在最高时连接数达到了8000,也就是到达了连接的上限才作罢。因此,我们需要为业务高峰期时保留足够的内存。
- 对于RAC数据库,需要考虑到其他节点故障或停机维护时,连接和压力转移到继续工作的节点时的内存消耗。
- 一些人只考虑到了连接时进程使用的PGA内存,这里存在一个很大的误解,就是认为一个连接,只会使用PGA的内存。但还有一个很重要的内存使用,那就是进程本身占用的操作系统内存,除了PGA之外的内存。进程本身有代码(在OS中这通常是共享的),有stack,有heap,还要有kernel的内存占用。PGA只是进程使用的内存中一部分,甚至大部分情况下只是一小部分。在Oracle 10.2.0.4 for AIX下测试过,一个空闲连接,也就是啥事儿都不干的一个连接,PGA占用500K左右,而server process进程占用的内存在4-5M之间。测试时这套库刚启动,没有任何负载。实际上据观察在一套运行比较长时间的库上,server process占用的内存在9-10M之间。当然不同的系统,不同的配置,oracle进程占用的内存有所不同,有兴趣的朋友可以测量一下Oracle进程在HP-UX和LINUX下的内存占用。
对于SGA内各组件的细分以及PGA大小设置,网上很多相关的文章可供参考,本文不再涉及。不过我的个人观点是:参数的调整也不是一步到位的事情,需要根据系统运行时对性能数据的分析来进行调整,直至达到最优化。
“参数的调整也不是一步到位的事情,需要根据系统运行时对性能数据的分析来进行调整,直至达到最优化。”非常赞同!
[回复]
我在一次中粮面试中遇到256内存,分配sga和pga问题了,当时答的很差,没考虑到进程本身占用内存这点。
我想问几个小问题:
1.我怎么查看空闲连接时些pga占用多少内存?
2.空闲连接时,server process占用多少内存?
3.上面两个问题能否以v$pgastat或是v$process中看到的值为准,为什么?
环境是rhle5 oracle 10.2.0.4单实例,如果您有时间帮解答下,谢谢!
[回复]
老熊 回复:
2月 25th, 2012 at 11:52 下午
@sunsyk,
1.查pga占用可以从v$process里面查。
2.空闲连接,进程的进程占用,可以用操作系统相关工具如pmap(aix上是procmap)来查看。
3.上述2个值是不同的含义。特别是进程占用的一些内存,是在oracle视图中查不到的。
[回复]
前些时间面试中粮时遇到一个问题256内存,oltp系统,并发3000,问如何分配sga和pga,当时回答很差,看这个帖子时发现进程本身所占内存没考虑。
您帖子里有提到:
在Oracle 10.2.0.4 for AIX下测试过,一个空闲连接,也就是啥事儿都不干的一个连接,PGA占用500K左右,而server process进程占用的内存在4-5M之间。
我想知道这个是怎么测试出来?
[回复]
老熊 回复:
2月 25th, 2012 at 11:53 下午
@sunsyk,
pga是从v$process中得到的。server process进程占用的内存用的是操作系统工具procmap。
[回复]
多谢!
[回复]
您好,有一些地方不明白,我负责的一个系统空闲连接PGA只占3M,但是server process却占用了100M,这是为什么呢,我查了很多个会话,server process基本都在90-150M之间,问题是我当时查看系统会话有2800多个,按每个进程100M就得280G的内存,实际上我的系统只有136G内存,这是怎么回事呢?多谢!
[回复]
老熊 回复:
5月 14th, 2012 at 10:13 下午
不知道你从哪个数据得到了server process占用了100M的结论。这里面肯定有共享内存部分,包括共享的代码,还有share memory的部分。要看server process占用的内存,只能看进程的private内存。
[回复]
我是用下面的命令看的:
$ps -ealf | head -1 ; ps -ealf | grep 2699382
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
240001 A oracle 2699382 1 3 61 20 38e9f45510 97792 11:32:32 – 0:04 oraclegzcrm1 (LOCAL=NO)
$procmap 2699382
2699382 : oraclegzcrm1 (LOCAL=NO)
100000000 95477K read/exec oracle
110000765 2399K read/write oracle
9fffffff0000000 51K read/exec /usr/ccs/bin/usla64
9fffffff000cfe2 0K read/write /usr/ccs/bin/usla64
90000000074b5e0 2K read/exec /usr/lib/libC.a[shr3_64.o]
9001000a020c5e0 0K read/write /usr/lib/libC.a[shr3_64.o]
9000000006d3800 115K read/exec /usr/lib/libC.a[shrcore_64.o]
9001000a0135400 12K read/write /usr/lib/libC.a[shrcore_64.o]
90000000069bf80 112K read/exec /usr/lib/libC.a[ansicore_64.o]
9001000a012b180 37K read/write /usr/lib/libC.a[ansicore_64.o]
9000000024ae468 0K read/exec /usr/lib/libicudata.a[shr_64.o]
9001000a0406468 0K read/write /usr/lib/libicudata.a[shr_64.o]
9000000007563e8 2K read/exec /usr/lib/libC.a[shr2_64.o]
9001000a020d3e8 0K read/write /usr/lib/libC.a[shr2_64.o]
9000000004fd200 1552K read/exec /usr/lib/libC.a[ansi_64.o]
9001000a020e800 269K read/write /usr/lib/libC.a[ansi_64.o]
9000000003d6d00 134K read/exec /usr/lib/libC.a[shr_64.o]
9001000a0139b00 19K read/write /usr/lib/libC.a[shr_64.o]
9000000022fc180 1732K read/exec /usr/lib/libicuuc.a[shr_64.o]
9001000a0407dac 180K read/write /usr/lib/libicuuc.a[shr_64.o]
900000002087d80 2510K read/exec /usr/lib/libicui18n.a[shr_64.o]
9001000a0435148 270K read/write /usr/lib/libicui18n.a[shr_64.o]
900000000682180 91K read/exec /usr/lib/libsrc.a[shr_64.o]
9001000a010e728 55K read/write /usr/lib/libsrc.a[shr_64.o]
900000000418500 743K read/exec /usr/lib/liblvm.a[shr_64.o]
9001000a013fe70 217K read/write /usr/lib/liblvm.a[shr_64.o]
900000000732100 97K read/exec /usr/lib/libcorcfg.a[shr_64.o]
9001000a0203448 18K read/write /usr/lib/libcorcfg.a[shr_64.o]
9000000006b9b80 81K read/exec /usr/lib/libcfg.a[shr_64.o]
9001000a0124490 26K read/write /usr/lib/libcfg.a[shr_64.o]
90000000069a380 2K read/exec /usr/lib/libcrypt.a[shr_64.o]
9001000a0102928 0K read/write /usr/lib/libcrypt.a[shr_64.o]
900000001f50520 5K read/exec /usr/lib/libc.a[aio_64.o]
9001000a0269228 0K read/write /usr/lib/libc.a[aio_64.o]
9000000003f9880 119K read/exec /usr/lib/libodm.a[shr_64.o]
9001000a0103688 40K read/write /usr/lib/libodm.a[shr_64.o]
9000000004e2e00 102K read/exec /usr/lib/libperfstat.a[shr_64.o]
9001000a02087b8 10K read/write /usr/lib/libperfstat.a[shr_64.o]
900000001f4f000 0K read/exec /usr/lib/libdl.a[shr_64.o]
9001000a0268000 0K read/write /usr/lib/libdl.a[shr_64.o]
900000005ee9100 8636K read/exec /oracle/product/10.2.0/db/lib/libjox10.a[shr.o]
8001000a0000b78 587K read/write /oracle/product/10.2.0/db/lib/libjox10.a[shr.o]
9000000006f1000 257K read/exec /usr/lib/libpthreads.a[shr_xpg5_64.o]
9001000a0177000 559K read/write /usr/lib/libpthreads.a[shr_xpg5_64.o]
900000000000100 3923K read/exec /usr/lib/libc.a[shr_64.o]
9001000a00004c0 1030K read/write /usr/lib/libc.a[shr_64.o]
Total 121494K
不知道您说的看进程的private内存,如何来看啊?多谢!
[回复]
老熊 回复:
5月 16th, 2012 at 12:36 下午
@老头, read/exec就是代码所占用的内存,这个是共享使用的,实际私有的内存是read/write部分,加在一起是5728K。
[回复]
哦。。好的。。多谢大师指点啊
[回复]
你好,我想问下,进程本身占用的操作系统内存,这部分内存算不算是sga里面的内存,还是和sga有重合?
[回复]
老熊 回复:
12月 31st, 2015 at 10:17 下午
进程本身占用的操作系统,跟SGA是没有重合的。
[回复]
进程本身占用的操作系统内存,这部分内存是属于sga吗,还是额外的其它的内存
[回复]