【新书连载】一波三折:释放内存导致数据库崩溃

编辑说明:《Oracle性能优化与诊断案例精选》出版以来,收到很多读者的来信和评论,我们会通过连载的形式将书中内容公布出来,希望书中内容能够帮助到更多的读者朋友们。

这是我一个运营商客户的案例。其现象大致是某天凌晨某RAC节点实例被重启了,通过如下的告警日志我们可以发现RAC集群的节点2实例被强行终止掉了,以下是详细的日志信息。

从上面的数据库告警日志来看,数据库实例2 从 2:03就开始报错ORA-00600 [KGHLKREM1],一直持续到2:39,lmd0进程开始报同样的错误,紧接着LMD0进程强行把数据库实例2终止掉了。

如果参照上述ORA-00600错误,直接搜索Oracle MOS,可能会搜到以下结果,Bug 14193240 : LMS SIGNALED ORA-600[KGHLKREM1] DURING BEEHIVE LOAD。但是这个Bug很容易被排除,根据系统监控就可以直接排除。在故障期间系统负载是非常低的。

这里我们需要注意,从告警日志来看,从2:03就开始报错,然而直到lmd0进程报错时,实例才被其终止掉。不难看出,数据库节点2的lmd0报错才是问题的关键。那么我们首先来分析数据库节点2的lmd0 进程的trace文件内容。

...省略部分内容...

从上面的信息来看,确实heap存在错误的情况。根据这个错误堆栈可以在MOS上再次匹配,这时找到文档号1070812.1的文章:ORA-600 [KGHLKREM1] On Linux Using Parameter drop_cache On hugepagesConfiguration,此次故障跟描述基本上一致。

其中地址[0x679000020]后面的内容也均为0,跟文档描述一样。其次,文章中提到使用了linux 内存释放机制以及同时启用了hugepage配置。根据文档描述,这应该是Linux Bug。通过检查对比2个节点配置,发现节点2的配置确实不同。

--节点1

[oracle@xxx-DS01 ~]$ cat /proc/sys/vm/drop_caches 0

--节点2

[oracle@xxx-DS02 ~]$ cat /proc/sys/vm/drop_caches 3

当drop_caches 设置为3时,会触发linux的内存清理回收机制,可能出现内存错误的情况。然而我们检查配置发现并没有修改。

既然没有修改配置文件,那么为什么会出现这种情况呢?

我怀疑是有人手工执行了echo3 > /proc/sys/vm/drop_caches命令来强制释放内存导致。接下来查看了最近几分钟的操作记录,发现了如下的蛛丝马迹。

很明显root 用户确实执行了内存释放的操作。然而运维人员却否认执行过类似操作,这说明事情并不是如此简单。我们进一步检查数据库操作系统日志发现如下信息。

我们可以看出,原来是由于调用了rel_mem.sh 脚本引发了这个问题,这个调用甚至导致CPU 1 挂起了10秒。对于Oracle RAC而言,当CPU 出现挂起,那么极有可能导致LMS等进程也挂起,进而引发数据库故障。

既然是调用了shell脚本,而客户的运维人员又没有主动做过任何操作,因此我怀疑很可能是之前部署了crontab 脚本,经过检查发现确实存在相关脚本,如下所示。

到这里我们已经清楚了原因,到此这个案例已经告一段落了。最后我们还应该深入思考,为什么客户要部署这样一个脚本呢?只有一种解释,说明这个数据库节点之前可能面临内存使用居高不下的问题。既然如此,那么就进一步检查一下目前系统的内存使用情况。

我们可以看到操作系统物理内存为128GB,而其中cache 内存就占据了88GB。Linux 文件系统的cache分为2种:pagecache和 buffer cache。page cache是用于文件inode等操作的,而buffer cache是用于块设备的操作。

上述 free -m 命令中的cached 88552 全是page cache。目前数据库实例的内存分配之后也就40GB。

由此可见,操作系统物理内存之所以看上去那么高,并非Oralce本身所消耗,大部分为文件系统cache所消耗。而对于Linux的文件系统缓存,我们是可以通过调整操作系统内核参数来加快回收的,并不需要使用前面提到的强制清理回收内存的暴力解决方式。

根据Oraclemetalink相关文档建议,通过设置如下参数来避免文本中的问题。

sysctl -wvm.min_free_kbytes=1024000 sysctl -wvm.vfs_cache_pressure=200 sysctl -wvm.swappiness=40

其中min_free_kbytes参数表示操作系统至少保留的空闲物理内存大小,单位是KB。vm.vfs_cache_pressure 参数用来控制操作系统对内存的回收,默认值为100,通过增加该值大小,可以加快系统对文件系统cache的回收。

而最后的参数vm.swappiness则是控制swap交换产生的趋势程度,默认值为100。通过将该值调得更低一些,可以降低物理内存和disk之间产生交换的概率。但是Redhat 官方白皮书中明确提出,不建议将该值设置为10或者更低的值。

实际上,通过我们的调整之后,据后续观察,该系统至今未再出现实例宕机的情况。这个案例告诉我们,在一个复杂的系统中,通过单一的手段进行粗暴的问题处理是危险的。正确的途径应该是,找出问题的根源,从源头对症下药,如此才能高枕无忧。

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2017-03-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

推荐Visual Studio 2010新功能-IntelliTrace(智能跟踪)

Visual Studio 2010 Ultimate 版本有个新功能IntelliTrace(智能跟踪),IntelliTrace被引入到Visula Stu...

1905
来自专栏WeTest质量开放平台团队的专栏

Linker加载so失败问题分析

原文链接:https://wetest.qq.com/lab/view/421.html

1201
来自专栏deepcc

jquery ajax 请求中多出现一次OPTIONS请求及其解决办法

1011
来自专栏Elson's web

【译】开始在web使用JS Modules

原文说的JS modules,实际上指的是ES6的模块化特性,通过<script type="module">可以实现不经过打包直接在浏览器中import/ex...

3207
来自专栏子勰随笔

我理解的高可用

2167
来自专栏LanceToBigData

JavaWeb(二)会话管理之细说cookie与session

前言   前面花了几篇博客介绍了Servlet,讲的非常的详细。这一篇给大家介绍一下cookie和session。 一、会话概述 1.1、什么是会话?   会话...

2347
来自专栏个人分享

分布式系统中的线程与进程

  虽然进程构成了分布式系统中的基本组成单元,但是操作系统提供的用于构建分布式系统的进程在粒度上还是太大了,而就粒度而言,将每个进程细分为若干控制线程的形式则更...

581
来自专栏腾讯开源的专栏

TarsGo新版本发布,支持protobuf,zipkin和自定义插件

Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架,目前支持C++,Java,PHP,Nodejs,Golang语言。该框架为用户提供了涉及到...

2557
来自专栏北京马哥教育

RabbitMQ源码解析前奏--partitions

一、集群与网络分区 RabbitMQ集群不能很好滴容忍网络分区。如果你正在考虑跨越广域网部署集群,则你最好使用federation或者shovel。 然而事故发...

2884
来自专栏deepcc

ajax 请求中多出现一次OPTIONS请求及其解决办法

W3C规范!在跨域请求中,分为简单请求(get和部分post,post时content-type属于application/x-www-form-urlenco...

3974

扫码关注云+社区