ORA-1034 ORA-27102
Table of Contents
没有足够的空闲内存. 这个问题很难分析。因为有时候,我们所依赖的操作系统命令,其实是在逗我们玩儿。 下面是我的一欠遍体鳞伤的经历,不堪回首呀。
1 现象
客户反馈数据库无法连接,报错信息如下:
SQL*Plus: Release 12.2.0.1.0 Production on Thu May 21 20:47:50 2020 Copyright (c) 1982, 2016, Oracle. All rights reserved. ERROR: ORA-01034: ORACLE not available ORA-27102: out of memory Linux-x86_64 Error: 12: Cannot allocate memory Additional information: 2731 Additional information: 557064 Additional information: 1744830464 Process ID: 0 Session ID: 0 Serial number: 0 Enter user-name:
2 分析
连接的时候无内存分配。。数据库连接的时候,都哪里需要内存呢?操作系统进程和oracle pga,但是后者所需很少. 先看物理内存吧。
[root@bossdb1 ~]# free -m total used free shared buff/cache available Mem: 64213 6219 25718 31115 32275 25987 Swap: 32191 0 32191
有25G 的空闲内存,哎哟,看来不是内存的问题,。难道是内核参数设置不正确或者分给Oracle 的内存用光了?如果是后者那太可怕了。
!就是从这儿开始,我在鬼打墙里转了两天!
2.1 内核参数
查看内核参数和用户限制吧。
# 查看用户最大允许锁定内存 [grid@bossdb1 ~]$ ulimit -m unlimited [oracle@bossdb2 ~]$ ulimit -m unlimited [grid@bossdb2 ~]$
都没有限制。 查看shmmax 和shmall:
[root@bossdb1 69431]# sysctl -a |grep kernel.shm kernel.shm_next_id = -1 kernel.shm_rmid_forced = 0 kernel.shmall = 16438528 kernel.shmmax = 67332210688 kernel.shmmni = 4096 ........
从上面查看的物理总内存为64G . 这里shmmax=67332210688/1024/1024/1024 = 62G shmall=16438528*4096/1024/1024/1024 = 62G
从这里看,也没有问题。
难道真的数据库把内存用光了?
2.2 数据库内存使用情况
-
内存上限
show parameter memory_max_target NAME TYPE VALUE ------------------------------------ -------------------------------- ------------------------------ memory_max_target big integer 50048M
-
SGA
select inst_id,sum(bytes)/(1024*1024*1024) from gv$sgainfo where name not in (‘Granule Size‘,‘Maximum SGA Size‘,‘Startup overhead in Shared Pool‘,‘Free SGA Memory Available‘) group by inst_id INST_ID SUM(BYTES)/(1024*1024*1024) ---------- --------------------------- 1 26.2499972 2 19.7499972
-
PGA
select inst_id,value/(1024*1024*1024) from gv$pgastat where name=‘total PGA allocated‘; INST_ID VALUE/(1024*1024*1024) ---------- ---------------------- 2 2.93612671 1 4.7712841
以上内存使用总量:
节点 内存使用量 1 26.25+4.77 = 31.02 2 19.75+2.94 = 22.69 两个节点内存使用远没有达到上限呢。
这是什么鬼??物理内存充足,Oracle 内存没有达到上限。怎么就无法分配内存了呢?难道是Oracle 12C BUG ?
MOS 查起来。。。发现没有BUG. 而且遇到这种情况的都是之前检查的内容。难道是进程数达到上限了?不对。达到进程数上限不是这个错误。
生无可恋了。。。。无心睡眠。。这是哪儿的问题。。 正好赶上客户要做变更。。晚上要停业务。。
重启是万能的法宝。晚上一起重启了吧。第二天,一个白天都灰常顺利。。开心下班。。以为这次就这么过去了。 可是刚到家。同事发来消息: 数据库又不能连了,跟昨天一样的错误。
我的以内那是一万匹草泥马奔腾而过…………….
从头开始。
-
物理内存
接着查看物理内存使用情况:
free -m total used free shared buff/cache available Mem: 64213 7209 33239 20670 23764 35384 Swap: 32191 0 32191
并没有太大的变化 。
top:
top - 23:51:30 up 1 day, 23:35, 4 users, load average: 1.99, 1.97, 2.06 Tasks: 699 total, 2 running, 697 sleeping, 0 stopped, 0 zombie %Cpu(s): 6.4 us, 2.0 sy, 0.0 ni, 85.6 id, 6.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 65754708 total, 34170344 free, 7248336 used, 24336028 buff/cache KiB Swap: 32964604 total, 32964604 free, 0 used. 36368028 avail Mem
并没有问题。虽然有预期,但是还是有点失望。随便看看吧。现在数据库有多少进程呀?
select inst_id,machine,program,count(*) from gv$session group by inst_id,machine,program order by 4; INST_ID MACHINE PROGRAM COUNT(*) ---------- ------------ ---------------------------- ---------- 2 bossdb2 oracle@bossdb2 (PING) 1 ............. 2 boss-ei1 JDBC Thin Client 13 1 ilogmaster shiyi@ilogmaster (TNS V1-V3) 23 1 KMGDCCWeb1 JDBC Thin Client 24 2 ipcc-hp-app JDBC Thin Client 522 1 ipcc-hp-app JDBC Thin Client 887
我个去,这是什么情况,一台应用服务器怎么连到数据库里有1400+ 进程。。都是活动的?
select inst_id,status,count(*) from gv$session where machine=‘ipcc-hp-app‘ group by inst_id,status; INST_ID STATUS COUNT(*) ---------- -------- ---------- 1 INACTIVE 862 2 INACTIVE 522 1 ACTIVE 1
都是不活动的。这些进程,占用了多少数据库内存,又占用了多少操作系统的物理内存?前者可能不大,但是后者肯定是有些恐怖的。
这些进程为什么不会退出呢?就算应用里没有退出机制,在数据库里也有空闲连接的配置呀:
col limit for a10 col resource_name for a15 col profile for a20 select profile,resource_name,limit from dba_profiles where resource_name = ‘IDLE_TIME‘; PROFILE RESOURCE_NAME LIMIT -------------------- --------------- ---------- DEFAULT IDLE_TIME UNLIMITED
居然是个Unlimited.
此刻我内心,其实已经倾向于是这些进程搞的鬼了。。。先把idle_time 限制起来吧。
alter profile default limit idle_time 180;
限制180,也就是3个小时,已经很长了。等一会儿,看看,果然pmon 已经清理超时进程了。
........ KILL SESSION for sid=(2973, 57359): Reason = profile limit idle_time Mode = KILL SOFT -/-/- Requestor = PMON (orapid = 2, ospid = 33310, inst = 1) Owner = Process: USER (orapid = 815, ospid = 95705) Result = ORA-0 .........
现在数据库也可以正常连接。那么基本可以肯定是这些进程搞的鬼。
但是,我心里仍有不甘。真的是这些进程搞得鬼么?还是只是凑巧,其他地方的问题也恢复了。
观察两天,之前重复出现的问题没有再出现。那么基本肯定是这些进程引起的问题。
研究很久,目前也没有找到方法统计进程占用的真实的物理内存,哎