Oracle内存过度消耗风险提醒

前言

时间过的真快,技术人生系列·我和数据中心的故事已经来到了第六期,小y又和大家见面了!

小y今天要和大家分享的是一个综合型问题的的分析和解决过程。

解决该类问题,只懂数据库是不够的,还需要掌握比较扎实的操作系统技能。

同时引出了另外一种不太常见形式的优化,内存优化。

由于今天要分享的问题具有普遍性,建议大家可以按照文中方法检查自己的系统中有无类似问题。分享的最后将对该共性的风险进行总结和提示。

如果觉得分享的案例还不错,麻烦亲们抬手转发一下,希望可以提醒和帮助到更多的客户。

更多Oracle数据库实战经验分享和风险提醒的首发,尽在“中亦安图”公众号!欢迎关注。

另外,近期有不少朋友问,小y所在团队是否可以做一些线下的分享?

确实,如果可以把大家组织起来,哪怕是一个会议室或者一个咖啡厅,除了面对面的技术分享,还可以聊聊人生,兴致来了还可以一起烧烤啤酒,结识更多的朋友,也是人生幸事!

既然大家有兴趣,那我们就开始第一期线下分享吧!

有兴趣参加北京、上海、广州、深圳等地线下分享的朋友,可以给小y发邮件,邮箱是51994106@qq.com,或者加小y的微信(shadow-huang-bj),提供城市、姓名、电话、单位、职位等信息即可,当报名人数超过20人,我们就开始启动北京、上海、广州、深圳、杭州、南京等地的免费线下分享活动。另外,有兴趣的可以加入QQ群227189100,我们以后会定期做一些线上的分享。

Part 1

问题来了

2015年12月28日,北京。

晚上8点,刚吃完晚饭,电话响起,是一位运营商客户的电话。

“小y,出事了,今天下午17点到18点,xx数据库监听和实例crash,不过现在库已经起来了。这个业务系统很重要,领导非常重视,务必要求查明原因。其他厂商都已经到了,暂时没有查到问题。你们能不能马上派个工程师到现场分析一下?争取今晚就有个结论!”

接到电话后,小y立刻安排兄弟赶往现场。之后还了解到,上周也出现过类似的问题。

环境介绍:

操作系统 AIX 6.1 TL8, 64-bit

数据库 ORACLE 11.2.0.3,2节点RAC

配置:16CPU 50G内存

Part 2

分析过程

过一会儿,收到日志,一下子来了精神,我们先来看看日志,确认下客户提到的数据库crash和监听crash的问题。

确认监听和数据库实例宕的问题

2.1.1

数据库alert.log

Oracle内存过度消耗风险提醒

可以看到:

>>17:42:39,数据库alert日志有关键报错信息,负责GCS的进程LMS的调用有89秒没有得到响应。意味着从17:41:10秒开始,数据库就开始出现问题了。

>>接下来,就来到了18:02:48,直接转到启动数据库的日志,没有数据库停止、被异常终止的日志,这20分钟内alert日志没有任何输出。期间操作系统并没有发生重启现象。

原因初步分析:

导致LMS的调用没有响应的最常见的原因是数据库所在的Lpar的系统资源如内存/CPU出现瓶颈。而通常在操作系统资源紧张的情况下,会伴随着以下表现:

>> CRS作为集群资源管理的进程,在检测资源时可能也会出现超时的情况,从而启动异常处理,例如将资源自动重启

>> RAC节点之间的某些心跳检测得不到响应的情况下,为了恢复整个RAC集群的对外服务能力,11g后将优先启动MemberKill,即终止数据库实例的方式尝试恢复,如果memberKill无法解决问题,则升级为NodeKill,即重启OS的方式来恢复整个集群的对外服务能力

接下来检查CRSD进程的日志

从中可以看到,包括VIP/监听等在内的资源,由于OS资源紧张的问题,检测超时,继而启动了异常处理。

2.1.2

节点1 CRSD.LOG

从下图可以看到:

17:42:30,CRSD检测VIP的健康情况,10秒后,检测超时,于是状态变UNKNOWN(然后被CRSD尝试重启)

Oracle内存过度消耗风险提醒

从下图可以看到:

17:51:18秒,由于VIP宕,而监听依赖于VIP,因此监听被请求停止。

从下图可以看到:

17:54:34,检测到数据库资源ora.XXDB.db被异常终止

2.1.3ocssd.log

从上图可以看到:

其实在2015-12-28 17:47:17,OCSSD进程就收到了节点2的Member kill request的请求,需要杀掉数据库实例。实际上,到了18:02:48,数据库才开始启动。

这期间经过了长达15分钟,说明数据库服务器资源已经很紧张,能导致性能如此缓慢的,通常只有内存出现大量换页。

2.2 操作系统性能-隐患早已埋下

从上述分析可以知道,事实上从17:41:10到17:42:39,数据库节点1系统资源就开始出现了紧张,开始变得缓慢了!

2.2.1

查看CPU使用情况

Oracle内存过度消耗风险提醒

可以看到:

CPU资源不是问题,CPU峰值并不高

2.2.2

查看内存换页情况(pi/po)

Oracle内存过度消耗风险提醒

可以看到:

NMON每5分钟采样一次,

17点39分的下一次采样是17点44分,但是这次采样根本没有被采集出来!

这说明系统资源已经非常紧张!这是最重要的一个证据!

问题出在17点42分,由于采集间隔的缘故,没有被采集到,也比较正常。

但不影响本次分析的总体判断。

另外,不难发现,在出问题以前,pageSpace的利用率达到12.44!说明以前就出现了内存不足!小y建议大家,如果发现自家AIX平台上出现pageSpace被使用的情况时,务必好好分析下内存的使用情况,否则将是一个大雷。

2.2.2

为什么会出现内存换页?

Oracle内存过度消耗风险提醒

小y看到该数据的时候,吓了一跳!

出问题前,如16:24到17:29之间,数据库服务器的计算内存(%comp)就已经长时间处于90%的高位了!这对于AIX来说,是非常危险的!对于计算内存,我们要尽量控制在80%以下,这样的系统才是出于健康状态的系统!

90%的计算内存已经接近内存换页的临界点!

当出现一些稍微大的内存的使用需求,则会使得系统出现内存换页。

那么到底是谁触发了换页呢?

在小y看来,如果一面墙快倒了,那么谁碰倒了这面墙不重要了!所以这不是问题的关键。

同样的17点44分本该显示有一条记录,却没打出来!

说明17点44分左右系统确实处于内存紧张状态。

17点49分时,计算内存更是达到了97%!(44分已经异常,必定导致进程堆积,继而加大内存的使用)

2.3 内存规划-客户的如意算盘

数据库服务器内存大小为50G,客户最开始的内存规划如下

>> SGA配置25G

>> PGA配置为5G

>> 数据库参数processes为2000,日常运行在1000个进程

数据库对内存的占用可以使用下面的简单公式来计算:

SGA + PGA+进程在OS级的消耗

正常情况下,11G版本数据库,单个ORACLE服务进程的内存占用在3M,

因此平时内存的使用为25G+5G+1000*3M=33G,占Lpar内存的66%。

如果按照出现异常等待,2000个进程被调起来的情况,则内存的使用为25G+5G+2000*3M=36G,规划偏大。

2.4 分析内存使用到底去哪了-现实很残酷

由于数据库对内存的占用可以使用下面的简单公式来计算:

SGA + PGA+进程在OS级的消耗

这里,SGA是个硬限制,PGA不是硬限制(无论工作区或非工作区都不是硬限制)

小y通过dba_hist_pgastat获得pga的峰值,发现也就是5个G,没有突破PGA的参数限制,那么最有可能的就是“进程在OS级的消耗”占的内存比较多了。

因此,小y马上通过 procmap命令检查单个进程的内存消耗:

发现ORACLE单个内存占用到了10M(将第二列加起来)

Oracle内存过度消耗风险提醒

到了这里,小y已经知道答案了!

读者朋友们,也可以停一下,把上述现象总结一下,再思考个几分钟,如果是你来接这个CASE,你会怎么继续往下查呢?

不要走开后边还有.....

那么内存用到了哪里呢?小y的做法很简单,通过svmon –P命令可以看到内存占用的细节。

Oracle内存过度消耗风险提醒

可以看到:

每个ORACLE服务进程work类型的独占内存中, USLA heap部分占了1642个内存页,而每页4K,即多占6-7M。

事实上这是一个操作系统和数据库的已知BUG。

中亦科技在其他数据中心已经遇到过好几次该问题。

2.5 不可小看的7M内存

数据库服务器内存大小为50G,客户最开始的内存规划如下

>> SGA配置25G

>> PGA配置为5G

>> 数据库参数processes为2000,日常运行在1000个进程

我们现在再来看一下:

正常情况下:

11G版本数据库,单个ORACLE服务进程的内存占用是10M而非3M!

因此平时内存的使用为25G+5G+1000*10M=40G,光数据库就占了内存的80%!这是比较危险的!对于AIX平台,数据库占内存建议在50%-60%之间,因为操作系统kernel等还会使用内存,最多可使用到40%,比较常见的是kernel inode cache的使用。

如果按照出现异常等待,2000个进程被调起来的情况,则内存的使用为25G+5G+2000*10M=50G

2.6 确认操作系统和数据库BUG

到这里后,就简单了。

小y在mos上以USLA做关键字搜索,以下就找到了对应的BUG.

下面的这篇note,是ORACLE官网上对于USLA heap导致单个进程多占7M内存,

从3M变成10M的BUG 13443029的描述。

11gR2Aix - Dedicated Server Processes Have Large Usla Heap Segment Compared To Older Versions (Doc ID 1260095.1)

2.7 如何解决呢?

这个问题是操作系统的一个缺陷,需要操作系统和数据库同时安装补丁才可以解决:

>> 对于AIX 6.1 TL07 or AIX 7.1 TL01需要操作系统和数据库同时安装补丁才可以解决。

>> 对于AIX 6.1 TL07 SP02/AIX 7.1 TL01 SP02 or later,由于操作系统已经修复,只需在数据库端安装补丁13443029。

数据库补丁13443029在11.2.0.3下不包含在任何PSU中,11.2.0.4中才包含了该问题的修复。

Part 3

原因总结和建议

3.1 原因总结

数据库服务器内存大小为50G,内存规划如下

Ø SGA配置25G

Ø PGA配置为5G

Ø 数据库参数processes为2000

28日平均数据库服务进程数为1000个左右

由于操作系统和数据库的一个已知缺陷--11gR2Aix - Dedicated Server Processes Have Large Usla Heap Segment Compared To Older Versions (Doc ID 1260095.1),导致一个空闲的数据库服务进程在USLA部分多占了7M左右的私有内存。

因此数据库整体占到了 25 G + 5G + 1000*10M=40G,即40G左右的计算内存,数据库已经占到80%以上的内存(通常要控制在60%),加上kernel等内存的使用,数据库平时运行在接近90%的计算内存的状态。这使得数据库服务器运行在内存高位下,当出现进程数增多、排序哈希等内存需求的时候,继而出现内存换页情况,将整体系统拖的异常缓慢。

内存紧张时本次故障的原因,最直接的证据如下:

NMON每5分钟采样一次,

17点39分的下一次采样是17点44分,但是这次采样没有被采集出来!

这说明系统资源已经非常紧张!这是最重要的一个证据!

数据库集群自身检测到VIP/数据库资源无响应的情况下,进行了异常处理,继而导致监听、VIP、数据库实例宕的故障。

3.2 建议

通过解决“操作系统和数据库关于USLA的缺陷“以及对数据库内存参数进行规划,可减少内存的使用,使得系统运行在更健康的内存状况下,从而从根本上解决该问题。

1) 安装数据库补丁13443029,使数据库重新以shrsymtab这个选项来编译,将USLA部分的7M内存减至几十K,从而多腾出来7G左右的内存(如果以2000个进程算,则腾出来14G内存)

2) 将数据库SGA内存sga_target参数从25G调小到20G。

调整说明:

经过两个调整后,在没有为lpar添加内存的情况下,

数据库的内存规划是 20G+5G+1000*3M=28G,如果算2000个进程跑满的情况下,数据库的内存规划是 20G+5G+2000*3M=31G

从而使得系统内存资源更富余,不会因为一些私有内存的需求而出现换页的情况。

Part 4

共性风险提醒

小y通过该案例,做出一些共性的风险提示:

不要低估一个空闲的Oracle服务进程所占用的内存带来的影响!

大家再做内存规划时,往往忽略了这一点!

如果您的数据库版本是11GR2,并且运行在AIX6/7的版本上,那么您的系统中很可能存在过度消耗内存的问题,即一个Oracle服务进程比10G版本的时候要多出7M左右的内存,从而使得单个ORACLE进程从3M变到10M。这对于Oracle服务进程数较多的数据库来说,是致命的。

例如,对于一个运行着2000个Oracle服务进程的数据库而言,所占用的内存不是2000*3=6G,而是2000*10=20G,多出14G。多出的14G将会超出你的内存规划,使数据库运行在危险状态下。是否命中该问题,可以参考文中分享的案例!

以下是ORACLE官网上对于USLA heap导致单个进程多占7M内存,

从3M变成10M的BUG 13443029的描述。

11gR2Aix - Dedicated Server Processes Have Large Usla Heap Segment Compared To Older Versions (Doc ID 1260095.1)

这个问题是操作系统的一个缺陷,需要操作系统和数据库同时安装补丁才可以解决:

>> 对于AIX 6.1 TL07 or AIX 7.1 TL01需要操作系统和数据库同时安装补丁才可以解决。

>> 对于AIX 6.1 TL07 SP02/AIX 7.1 TL01 SP02 or later,由于操作系统已经修复,只需在数据库端安装补丁13443029。

数据库补丁13443029在11.2.0.3下不包含在任何PSU中,11.2.0.4中才包含了该问题的修复。

For AIX 6.1 TL07 SP02/AIX 7.1 TL01 SP02 or later, apply patch 13443029

For AIX 6.1 TL07 or AIX 7.1 TL01, install AIX 6.1 TL-07 APAR

IV09580, AIX 7.1 TL-01 APAR IV09541, and apply patch 13443029

For other AIX level, apply patch 10190759, this will disable Oracle's online patching mechanism

Note: as of 06/21/2012, fix for bug 13443029 or bug 10190759 are not included in any PSU and the interim patch is needed. Interim patch 10190759 exists on top of most PSU, and patch 13443029 on top of 11.2.0.3 does not conflict with 11.2.0.3.1 PSU and can be applied on top of both 11.2.0.3 base and 11.2.0.3.1 PSU.

上一篇:【中亦安图】Oracle内存过度消耗风险提醒(6)


下一篇:从Oracle数据库故障到AIX内存管理