问题描述

Linux服务器SAP-HANA经常系统内存不足使得SAP应用不能使用解决方案。
Linux内存使用量过高,使得sap应用程序无可用内存,最终导致程序崩溃。

问题原因

自己查阅了一些资料,也基于zabbix的可用内存和实际不太一样入手去找原因发现问题出现于Cached的值过大,导致系统没有可以再分配的内存空间。Cached只要用来缓存文件的,经常读写的文件会被缓存到Cached中,可以增加读写效率,该功能是Linux系统内核提供的,而SAP-HANA的日志文件很大过一段时间基本都是好几百G。这就可以解释SAP项目总是过一段时间就挂掉了,SAP处理的数据量很大,所以接收和下载的文件会被缓存起来,一直耗着内存不释放,即使把程序停掉也不会释放内存。
1.SAP发生问题时内存的使用情况
在这里插入图片描述
可以看到cached很大,达到了200多G
重启之后的HANA内存使用情况,很明显cached的值降到7G多,这也是为什么重启之后问题貌似解决了,但是多了一段时间之后却还是会出现新的问题。
在这里插入图片描述
在这里插入图片描述

可以看到按照此公式计算可用内存为200多G,这也正是zabbix所监控到的数据,是没有问题的。所以问题就在于还有可用内存但是我们却不能用,原因就在于Cached的值过大,导致系统没有可以再分配的内存空间。
这也是为什么zabbix报警swap分区使用过高的原因,由于缓存空间(Cached)有限,在很紧张时会使用swap的空间。
问题解决办法
最后找到了三条执行,可以清理cached的内存。
三条指令:
sync
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches
执行完这三条指令后通过free -m命令查看,free可用内存马上增多,buff/cache列值变小,说明内存被释放了,但是不能总是手动的执行这三条指令,所以具体工作中要写一个shell脚本,开启Linux定时任务crond,每天早上检查一次free内存,当小于一定的值时执行这三条命令。具体我这边在写,具体后面可以在观察,有问题请联系我。
注意:在执行这三条命令之前一定要先执行sync命令(描述:sync 命令运行 sync 子例程。如果必须停止系统,则运行sync 命令以确保文件系统的完整性。sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-Node、已延迟的块 I/O 和读写映射文件)

解决方案(手动)

  1. 修改/proc/sys/vm/drop_caches,释放Slab占用的cache内存空间(参考drop_caches的官方文档):
    在这里插入图片描述
    注意:在执行这三条命令前先执行sync命令
    解决方案(自动)
    1、编写shell定时任务脚本freemem.sh
    #! /bin/sh
    used= free -m | awk 'NR==2' | awk '{print $3}'
    free= free -m | awk 'NR==2' | awk '{print $4}'
    echo “===========================” >> /app/memory/logs/mem.log
    date >> /app/memory/logs/mem.log
    echo “Memory usage before | [Use:usedMB][Free:{used}MB][Free:usedMB][Free:{free}MB]” >> /app/memory/logs/mem.log
    if [ $free -le 4000 ] ; then
    sync && echo 1 > /proc/sys/vm/drop_caches
    sync && echo 2 > /proc/sys/vm/drop_caches
    sync && echo 3 > /proc/sys/vm/drop_caches
    used_ok= free -m | awk 'NR==2' | awk '{print $3}'
    free_ok= free -m | awk 'NR==2' | awk '{print $4}'
    echo “Memory usage after | [Use:usedokMB][Free:{used_ok}MB][Free:usedo​kMB][Free:{free_ok}MB]” >> /app/memory/logs/mem.log
    echo “OK” >> /app/memory/logs/mem.log
    else
    echo “Not required” >> /app/memory/logs/mem.log
    fi
    exit 1
    2、使用crontab -e命令编辑当前用户的crontab 0 6 * * * /usr/local/tomcat/sztFileFront/bin/freemem.sh
    定时任务编写参考:http://www.jb51.net/article/15008.htm

3、重启crond服务

/sbin/service crond restart

4、查看crond服务是否重启成功

/sbin/service crond status

最后,问题解决。我设定的定时任务是每天早上6点执行一次freemem.sh脚本。
在这里插入图片描述