上一篇文章主要介绍了x86/x86_64架构使用hugepages的可能带来的潜在的好处,本篇则继续上一篇的话题,通过一个典型的案例介绍没有使用hugepages所带来的问题以及与之相关的一些延伸话题。
某 客户新上线的Oracle数据库系统,运行在Linux x86_64平台上,主机配置较高,32核+120G内存,SGA设置90G左右,但是每当数据库运行大约一周以后,前台应用就会变得异常缓慢,经常假 死,有时新连接都没有响应,如果DBA不加干涉杀掉部分local=NO的进程,过一段时间就可能有节点被驱逐。
经过简单的分析,当前数据库主机有如下一些特征:
- 前台响应缓慢或者新连接无法建立时,CPU占用率并不高,但是奇怪的是有一个系统进程kswapd0占据了单核CPU的100%,其它进程的CPU占用率都控制在单核的各位数;
- 通过free命令来查看剩余内存,发现所剩的内存已经不多,通过sar -B和vmstat查看发现有较为严重的page in和page out。
- 问题发生时刻,连接数有一定程度的增加,但是基本都是呈缓慢线性的方式增加,没有剧增的情况。从oracle进程来看,每个连接占的CPU和内存资源都差不多;
- 从/proc/meminfo来看,页表占用了内存的绝大部分;
- 操作系统重启的时候,在/var/logs/message中有类似的信息:
messages: Feb 10 10:11:40 rac 01kernel: SysRq : Resetting messages:Feb 10 10:16:35 rac01 syslogd 1.4.1: restart.
这个问题并不复杂:本质就是一个内存耗尽的问题,但是另客户非常不解的是:按照规划,物理内存应该是绰绰有余的, 那为什么还出现了内存耗竭的情况呢?
当然,如果有看过前面的文章就知道,因为没有配置hugepages,导致了随着连接数的增加页表急剧膨胀,并且SGA被频繁的从swap交换空间换入/换出。
在Linux中, kswapd是负责内核页面交换管理的一个守护进程, 它的职责是保证Linux内存管理操作的高效。当物理内存不够时,它就会变得非常aggressive,就像上文中所说的能占用单核CPU的100%.
kswapd 进程负责确保内存空间总是在被释放中, 它监控内核中的pages_high和pages_low阀值。如果空闲内存的数值低于pages_low,则每次 kswapd 进程启动扫描并尝试释放32个free pages.并一直重复这个过程,直到空闲内存的数值高于 pages_high。kswapd 进程完成以下几个操作: 1,如果该页处于未修改状态,则将该页放置回空闲列表中. 2,如果该页处于已修改状态并可备份回文件系统,则将页内容写入到磁盘. 3,如果该页处于已修改状态但没有任何磁盘备份,则将页内容写入到swap device.
注: 每次 kswapd 进程启动扫描并尝试释放32个free pages 不再适用于RHEL 5.4以后的版本。
以 上方框中的内容来自Linux System and Performance Monitoring, 原文链接已不可考。当然也可以参考MOS文档kswapd / krefilld Process Consumes All the CPU Resources [ID 272249.1], 尽管是一篇很老的文章了。
另外这里还有一个有意思的特性我是没有注意到的: CRS会使用SysRq reset来重启节点。ocssd进程最后会调用一条神奇的命令来进行“自杀”:
echo b > sysrq-trigger
注意:这条命令属于非常危险的Linux命令,请不要到生产系统尝试,否则后果自负。sysrq在Linux中叫做“神奇的SysRq键” (参见wikipedia条目: Magic SysRq Key), 之所以叫“键”是因为在你的键盘上也有一个这样的实体按键, 在x86平台,使用”<ALT> + SysRq + <command key>“就可以完成对应的功能。以下罗列这条命令常见的选项(以下来在MOS文档Alt SysRq Keys Utility on Enterprise Linux [ID 228203.1]):
- Alt+SysRq+r use Raw keyboard events
- Alt+SysRq+k kill current VT in use
- Alt+SysRq+e terminate all running processes (except init)
- Alt+SysRq+i kill all processes (except init)
- Alt+SysRq+l kill all processes (including init)
- Alt+SysRq+b reboot
- Alt+SysRq+s sync all drives
- Alt+SysRq+u umount all filesystems
- Alt+SysRq+o turn the machine Off
- Alt+SysRq+p dump Processor’s registers: shows process executing in each processor
- Alt+SysRq+c reboot kexec and output a crashdump
更详细的内容,请参考Linux内核文档https://www.kernel.org/doc/Documentation/sysrq.txt
在10gR2的AIX平台中,/etc/init.cssd文件中会有SYSDUMP这样的条目,主要作用就是确保如果是CRS重启了主机,在重启之前会生成一个system dump的信息,不过这个条目在11gR2已经被移除。
同样在Linux平台,借助SysRq也能实现失事前留下“黑匣子“的功能,方面查找原因。以下是Linux平台对应的Enhancement Request:
Bug 11866171 Linux: Enable Crashdump when rebooting the machine
Once the patch is applied, please run the following commands to turn on the crash dump: crsctl modify type ora.cssd.type -attr "ATTRIBUTE=REBOOT_OPTS, TYPE=string, DEFAULT_VALUE=,FLAGS=CONFIG" -init crsctl modify type ora.cssdmonitor.type -attr "ATTRIBUTE=REBOOT_OPTS, TYPE=string, DEFAULT_VALUE=,FLAGS=CONFIG" -init crsctl modify res ora.cssd -attr "REBOOT_OPTS=CRASHDUMP" -init crsctl modify res ora.cssdmonitor -attr "REBOOT_OPTS=CRASHDUMP" -init To disable the crash dump: crsctl modify res ora.cssd -attr "REBOOT_OPTS=" -init crsctl modify res ora.cssdmonitor -attr "REBOOT_OPTS=" -init
这个Enhancement的主要作用就是将可能会重启主机的进程的重启的属性从
echo "b" > /proc/sysrq-trigger
修改为:
echo "c" > /proc/sysrq-trigger
因为传递c标志在重启前会生成crash dump文件。
通过前面几篇文章,我们可以总结,在对大内存进行管理的时候, hugepages怎么强调都不过分。