一、故障处理
客户一台Linux系统频繁重启,工程师接到报修电话后登录查看,发现日志中大量的oom,内存溢出告警,每次重启后,不启动任何应用程序,主机内存很快被占满;同时其余客户端使用sftp传输数据,经常因内存溢出导致传输失败,影响业务。
二、故障排除
2.1 messages文件内容
Dec 24 15:49:55 xxxxxxxxxxxx kernel: [ 52.671197] BIOS EDD facility v0.16 2004-Jun-25, 2 devices found
Dec 24 15:49:56 xxxxxxxxxxxx kernel: [ 53.763632] oom_kill_process: 21 callbacks suppressed
2.2 系统资源使用情况
与客户沟通得知,PotralAgent是常规进程,其他机器也有此进程,资源使用无异常。
可以看到主机配置了8G内存,已经所剩无几,同时swap也有一部分被使用,说明内存资源紧张。
2.3 内存使用分析
重启前后内存信息对比
重启前 | 重启后 |
MemTotal: 8062712 kB MemFree: 590024 kB Buffers: 2584 kB Cached: 30332 kB SwapCached: 832 kB | MemTotal: 8062712 kB MemFree: 566876 kB Buffers: 968 kB Cached: 16080 kB SwapCached: 552 kB |
AnonHugePages: 0 kB | AnonHugePages: 0 kB |
Slab: 35932 kB SReclaimable: 4900 kB SUnreclaim: 31032 kB KernelStack: 1704 kB PageTables: 3916 kB | Slab: 35308 kB SReclaimable: 3736 kB SUnreclaim: 31572 kB KernelStack: 1304 kB PageTables: 2432 kB |
HugePages_Total: 3559 HugePages_Free: 3559 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB | HugePages_Total: 3580 HugePages_Free: 3580 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB |
CommitLimit: 10872696 kB Committed_AS: 197048 kB | CommitLimit: 10851192 kB Committed_AS: 542772 kB |
DirectMap4k: 57344 kB DirectMap2M: 8331264 kB | DirectMap4k: 57344 kB DirectMap2M: 8331264 kB |
通过以上分析,内存超分问题不严重,未开启THP。
故障原因已经很明显:2M的页面缓存量有8GB之多(8331264/1024/1024),再加上其他的内存开销,显然已经超过系统物理内存之和。
2.4 查看系统配置
cat /proc/sys/vm/nr_hugepages
3559
cat /etc/sysctl.conf|grep nr_hugepages
vm.nr_hugepages = 5120
可以看到系统配置了5120个大页,但是实际运行当中分配了3559个页面(3559*2048/2=7GB)。
三、故障处理
将nr_hugepages值调小或者直接取消,就不会引起系统内存被占满的情况,故障得到解决。
四、经验总结
4.1 HugePages介绍
随着计算需求规模的不断增大,应用程序对内存的需求也越来越大。为了实现虚拟内存管理机制,操作系统对内存实行分页管理。自内存“分页机制”提出之始,内存页面的默认大小便被设置为 4096 字节(4KB),虽然原则上内存页面大小是可配置的,但绝大多数的操作系统实现中仍然采用默认的 4KB 页面。 4KB 大小的页面在“分页机制”提出的时候是合理的,因为当时的内存大小不过几十兆字节,然而当物理内存容量增长到几 G 甚至几十 G 的时候,操作系统仍然以 4KB 大小为页面的基本单位,是否依然合理呢?
在 Linux 操作系统上运行内存需求量较大的应用程序时,由于其采用的默认页面大小为 4KB,因而将会产生较多 TLB Miss 和缺页中断,从而大大影响应用程序的性能。当操作系统以 2MB 甚至更大作为分页的单位时,将会大大减少 TLB Miss 和缺页中断的数量,显著提高应用程序的性能。这也正是 Linux 内核引入大页面支持的直接原因。好处是很明显的,假设应用程序需要 2MB 的内存,如果操作系统以 4KB 作为分页的单位,则需要 512 个页面,进而在 TLB 中需要 512 个表项,同时也需要 512 个页表项,操作系统需要经历至少 512 次 TLB Miss 和 512 次缺页中断才能将 2MB 应用程序空间全部映射到物理内存;然而,当操作系统采用 2MB 作为分页的基本单位时,只需要1次 TLB Miss 和1次缺页中断,就可以为 2MB 的应用程序空间建立虚实映射,并在运行过程中无需再经历 TLB Miss 和缺页中断(假设未发生 TLB 项替换和swap)。
为了能以最小的代价实现大页面支持,Linux 操作系统采用了基于 hugetlbfs 特殊文件系统 2M 字节大页面支持。这种采用特殊文件系统形式支持大页面的方式,使得应用程序可以根据需要灵活地选择虚存页面大小,而不会被强制使用 2MB 大页面。
4.2 THP
透明巨页(Transparent Huge Pages)缩写为 THP,透明超大页面(THP)在 RHEL 6 中默认情况下对所有应用程序都是启用的。内核试图尽可能分配巨大的页面,主内核地址空间本身被映射为巨大的页面,减少了内核代码的 TLB 压力。内核将始终尝试使用巨页来满足内存分配。如果没有可用的巨大页面(例如由于物理连续内存不可用),内核将回退到正常的 4KB 页面。THP 也是可交换的(不像 hugetlbfs)。这是通过将大页面分成更小的 4KB 页面来实现的,然后这些页面被正常地换出。
4.3 THP注意事项
静态huge page拥有一套独立的内存系统,与4KB的normal page构成的普通内存,静态huge page也不支持swap操作,不能被换出到外部存储介质上。
THP和静态huge page看起来样子差不多,但在Linux中的归属和行为却完全不同。可以这样理解,后者是一体成型的,而前者就像是焊接起来的。THP本质还是和normal page更相像。
THP在需要swap时,swap out的时候打散成4KB,交换到磁盘空间;swap in的时候可能又需要重新聚合回来,这对性能的影响是不言而喻的。
Oracle 官方不建议在使用 RedHat 6/OEL 6/SLES 11 / UEK2 kernels 时开启透明巨页(THP),因为透明巨页存在一些问题:
在 RAC 环境下,透明巨页(THP)会导致异常节点重启和性能问题;
在单机环境中,透明巨页(THP)也会导致一些异常的性能问题。
4.4 HugePages和THP两者区别
两者区别在于大页的分配机制,标准大页管理是预分配方式,而透明巨页管理则是动态分配方式。目前透明巨页与传统大页混合使用会出现一些问题,导致性能问题和系统重启。
4.5 HugePages注意事项
HugePages 会在系统启动时,直接分配并保留对应大小的内存区域;
HugePages 在开机之后,如果没有管理员的介入,不会释放和改变;
HugePages使用的是共享内存,在操作系统启动期间被动态分配并被保留,因为他们不会被置换;
对于只使用Oracle的服务器来说,把Hugepages设置成SGA(所有instance SGA之和)大小即可;
如果增加HugePages或添加物理内存或者是当前服务器增加了新的instance以及SGA发生变化,应该重新设置所需的HugePages。
4.6 SUSE & RedHat
更改nr_hugepages后,Centos、RedHat系统受影响不大,内存不会立刻下降,SUSE系统会立刻占满内存。
五、知识拓展
5.1 开启HugePages
编辑sysctl.conf
vi /etc/sysctl.conf
vm.nr_hugepages = xxxx
编辑limits.conf
vi /etc/security/limits.conf
* soft memlock -1
* hard memlock -1
生效
sysctl -p
验证
grep -i hugepages /proc/meminfo
5.2 Oracle使用HugePages
11.2.0.2之前的版本,database的SGA只能选择全部使用hugepages或者完全不使用hugepages;
11.2.0.2 及以后的版本, oracle增加了一个新的参数“USE_LARGE_PAGES”来管理数据库如何使用 hugepages;
USE_LARGE_PAGES参数有三个值: "true" (default), "only", "false" and "auto"(since 11.2.0.3 patchset):
默认值是"true",如果系统设置Hugepages的话,SGA会优先使用hugepages,有多少用多少;
11.2.0.2 如果没有足够的 hugepages, SGA是不会使用hugepages的. 这会导致ORA-4030错误,因为hugepages已经从物理内存分配,但是SGA没有使用它,却使用其他部分内存,导致内存资源不足;
但是在11.2.0.3版本这个使用策略被改变了,SGA可以一部分使用hugepages,剩余部分使用small pages。这样,SGA会有限使用hugepages,在hugepages用完之后,再使用regular sized pages。
如果设置为"false" , SGA就不会使用hugepages;
如果设置为 "only" 如果hugepages大小不够的话,数据库实例是无法启动的 (防止内存溢出的情况发生);
11.2.0.3版本之后,可以设置为 "auto",这个选项会触发oradism进程重新配置linux内核,以增加hugepages的数量。Oradism需要被赋予相应的权限,如下:
-rwsr-x--- 1 root 它不会去改变/etc/sysctl.conf文件中的hugepages值,当OS重启后,系统会再恢复到/etc/sysctl.conf中配置的hugepages值。
对于只使用Oracle的服务器来说,把Hugepage设置成SGA(所有instance SGA之和)大小即可;
如果增加HugePage或添加物理内存或者是当前服务器增加了新的instance以及SGA发生变化,应该重新设置所需的HugePage。
5.3 关闭THP
查看THP是否开启
[always] madvise never
[root@coding ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
[root@coding ~]# cat /sys/kernel/mm/transparent_hugepage/defrag
关闭THP
编辑/etc/rc.local,添加如下内容:
echo "never" >/sys/kernel/mm/transparent_hugepage/enabled
echo "never" >/sys/kernel/mm/transparent_hugepage/defrag
5.4 HugePages设置脚本
执行此脚本,会给出建议值。
执行此脚本,需要安装bc rpm包。
使用oracle用户运行,并确保实例正常启动。
#! /bin/bash
#
# hugepages_settings.sh
#
# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
# on Oracle Linux
#
# Note: This script does calculation for all shared memory
# segments available when the script is run, no matter it
# is an Oracle RDBMS shared memory segment or not.
#
# This script is provided by Doc ID 401749.1 from My Oracle Support
# http://support.oracle.com
if [ $(rpm -qa|grep ^bc) ]
then
echo "Already install bc rpm package,contine."
else
echo "Please install bc rpm package within os medium."
exit
fi
# Welcome text
echo "
This script is provided by Doc ID 401749.1 from My Oracle Support
(http://support.oracle.com) where it is intended to compute values for
the recommended HugePages/HugeTLB configuration for the current shared
memory segments on Oracle Linux. Before proceeding with the execution please note following:
* For ASM instance, it needs to configure ASMM instead of AMM.
* The 'pga_aggregate_target' is outside the SGA and
you should accommodate this while calculating SGA size.
* In case you changes the DB SGA size,
as the new SGA will not fit in the previous HugePages configuration,
it had better disable the whole HugePages,
start the DB with new SGA size and run the script again.
And make sure that:
* Oracle Database instance(s) are up and running
* Oracle Database 11g Automatic Memory Management (AMM) is not setup
(See Doc ID 749851.1)
* The shared memory segments can be listed by command:
# ipcs -m
Press Enter to proceed..."
read
# Check for the kernel version
KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'`
# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
if [ -z "$HPG_SZ" ];then
echo "The hugepages may not be supported in the system where the script is being executed."
exit 1
fi
# Initialize the counter
NUM_PG=0
# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | cut -c44-300 | awk '{print $1}' | grep "[0-9][0-9]*"`
do
MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
if [ $MIN_PG -gt 0 ]; then
NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q`
fi
done
RES_BYTES=`echo "$NUM_PG * $HPG_SZ * 1024" | bc -q`
# An SGA less than 100MB does not make sense
# Bail out if that is the case
if [ $RES_BYTES -lt 100000000 ]; then
echo "***********"
echo "** ERROR **"
echo "***********"
echo "Sorry! There are not enough total of shared memory segments allocated for
HugePages configuration. HugePages can only be used for shared memory segments
that you can list by command:
# ipcs -m
of a size that can match an Oracle Database SGA. Please make sure that:
* Oracle Database instance is up and running
* Oracle Database 11g Automatic Memory Management (AMM) is not configured"
exit 1
fi
# Finish with results
case $KERN in
'2.2') echo "Kernel version $KERN is not supported. Exiting." ;;
'2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`;
echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;;
'2.6') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
'3.8') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
'3.10') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
'4.1') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
esac
# End
如欲了解更多,请登录365bet足球比分官方网站:09t2.sockssky.com