案例描述:用户报告,服务器启动一段时间以后,无法建立数据库连接。重新启动几分钟以后,再次无法连接。
操作系统:SunOS 5.8,系统无法正常使用.
1. 登陆数据库,检查系统进程
登陆系统,检查系统进程,发现后台进程正常,有一定量的用户连接:
wapplatform:/>su - oracle Sun Microsystems Inc. SunOS 5.8 Generic Patch October 2001 You have new mail. /export/home1/oracle/admin>ps -ef|grep ora oracle 25269 25258 0 13:58:36 pts/3 0:00 grep ora oracle 25267 1 1 13:58:34 ? 0:00 oracleHSWAPDB (LOCAL=NO) oracle 25193 1 0 13:57:03 ? 0:01 oracleHSWAPDB (LOCAL=NO) oracle 25209 1 0 13:57:09 ? 0:00 oracleHSWAPDB (LOCAL=NO) oracle 25244 1 1 13:58:23 ? 0:00 oracleHSWAPDB (LOCAL=NO) oracle 25218 1 0 13:57:23 ? 0:00 oracleHSWAPDB (LOCAL=NO) ............... oracle 25149 1 0 13:56:41 ? 0:01 ora_lgwr_HSWAPDB oracle 25153 1 0 13:56:42 ? 0:01 ora_smon_HSWAPDB oracle 25155 1 0 13:56:42 ? 0:00 ora_reco_HSWAPDB oracle 25151 1 0 13:56:41 ? 0:00 ora_ckpt_HSWAPDB oracle 25145 1 0 13:56:41 ? 0:00 ora_dbw0_HSWAPDB oracle 25143 1 0 13:56:41 ? 0:00 ora_pmon_HSWAPDB ......
2. 检查警报日志文件
发现如下大量提示信息:
Tue Mar 23 13:40:45 2004 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 skgpspawn failed:category = 27142, depinfo = 11, op = fork, loc = skgpspawn5 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3 Tue Mar 23 13:42:02 2004 skgpspawn failed:category = 27142, depinfo = 12, op = fork, loc = skgpspawn3
该提示说明系统无法fork新的数据库进程,数据库无法spawn a new session:
而且这里 "skgpspawn failed:category = 27142"实际上应该是Oracle的错误号,我们可以通过Oracle的手册查询到这个错误的具体内容,在Unix/Linux上我们可以通过oerr工具获得相关信息:
$ oerr ora 27142 27142, 0000, "could not create new process" // *Cause: OS system call // *Action: check errno and if possible increase the number of processes
3. 尝试连接数据库
当再次尝试连接数据库时,收到如下错误信息,无法连接数据库:
$ sqlplus "/ as sysdba" SQL*Plus: Release 9.2.0.3.0 - Production on 星期二 3月 23 14:14:06 2004 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. ERROR: ORA-12540: TNS: 超出内部限制 请输入用户名: ERROR: ORA-12540: TNS: 超出内部限制 请输入用户名: ERROR: ORA-12540: TNS: 超出内部限制 SP2-0157: 在3次尝试之后无法 CONNECT 到 ORACLE, 退出 SQL*Plus
内部限制超过,通常说明某些系统资源不足.
4. 检查系统日志
检查系统日志信息,发现大量失败的su操作,有swap区不足的报告:
wapplatform:/>dmesg 2004年03月23日 星期二 14时00分32秒 CST Mar 23 13:40:56 wapplatform su: [ID 810491 auth.crit] 'su root' failed for root on /dev/pts/2 Mar 23 13:46:26 wapplatform genunix: [ID 470503 kern.warning] WARNING: Sorry, no swap space to grow stack for pid 24888 (sqlplus) Mar 23 13:49:18 wapplatform su: [ID 810491 auth.crit] 'su oracle' failed for root on /dev/pts/6 Mar 23 13:54:03 wapplatform genunix: [ID 470503 kern.warning] WARNING: Sorry, no swap space to grow stack for pid 25035 (su) Mar 23 13:54:08 wapplatform genunix: [ID 470503 kern.warning] WARNING: Sorry, no swap space to grow stack for pid 25036 (su) 现在基本可以判断是交换区的问题,当然和Oracle SGA设置有关.
5. 检查系统内存及交换区使用
通过TOP工具检查系统内存及Swap使用情况:
$ top last pid: 25456; load averages: 0.67, 0.70, 0.69 14:10:03 93 processes: 91 sleeping, 2 on cpu CPU states: 72.7% idle, 14.9% user, 2.7% kernel, 9.7% iowait, 0.0% swap Memory: 1024M real, 34M free, 752M swap in use, 10M swap free PID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND 25199 oracle 1 40 0 674M 631M cpu/2 8:03 16.32% oracle 25209 oracle 1 30 0 675M 630M sleep 0:03 0.13% oracle 25159 oracle 1 48 0 674M 628M sleep 0:03 0.06% oracle 25384 oracle 1 58 0 2632K 1736K cpu/0 0:01 0.05% top 25145 oracle 143 58 0 682M 630M sleep 0:01 0.03% oracle
发现物理内存仅为1G,free部分为34M,交换区使用了752M,仅Swap Free部分仅余10M 。由此我们知道系统内存严重不足,Swap区不足。
6. 检查数据库的SGA设置
发现SGA设置为: 622299344 bytes,接近600M,这个SGA设置过高: /export/home1/oracle>sqlplus "/ as sysdba" SQL*Plus: Release 9.2.0.3.0 - Production on 星期二 3月 23 14:02:30 2004 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. 连接到: Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production With the Partitioning, OLAP and Oracle Data Mining options JServer Release 9.2.0.3.0 - Production SQL> show sga Total System Global Area 622299344 bytes Fixed Size 731344 bytes Variable Size 268435456 bytes Database Buffers 352321536 bytes Redo Buffers 811008 bytes
对于RAM小于1G的系统,Dedicated模式下,通常我们建议Oracle的SGA一般不应超过1/2物理内存,SGA之外我们还应考虑到PGA及操作系统的内存分配。
7. 调整内容
第一步调整,减小SGA,为系统保留足够的内存。
第二步调整,为系统增加swap区。
wapplatform:/var/swap>cd /export/home1 wapplatform:/export/home1>mkdir swap wapplatform:/export/home1>cd swap wapplatform:/export/home1/swap>mkfile -v 1g swapfile1 swapfile1 1073741824 bytes wapplatform:/export/home1/swap>swap -a /export/home1/swap/swapfile1 wapplatform:/export/home1/swap>swap -s
总数:分配了 623160k 字节 + 保留 162704k = 已使用 785864k,1010936k 可用
至此系统恢复正常,问题解决
7. 问题总结:
Oracle数据库问题的解决从来就离不开操作系统,很多时候我们必须通过操作系统一级的手段来诊断并解决问题。
关于操作系统,一般Swap区的推荐值为2*RAM。如果物理内存(RAM)很大,不一定非要把Swap设置为2xSwap,通常可以设置Swap = Ram或者小于物理内存(如内存超过32G则完全可以设置Swap为16G)。如果物理内存(RAM)过小,在系统繁忙期间,产生大量交换无法换到磁盘,就会出现问题,如本案例就是这样。
另外,如果系统物理内存较小,通常设置SGA < 1/2 Ram,要考虑为Server process的PGA消耗及OS保留足够的内存空间.