当前位置:  数据库>oracle

使用HugePages优化内存性能

    来源: 互联网  发布时间:2017-06-14

    本文导语: 1. 引子 系统进程是通过虚拟地址访问内存,但是CPU必须把它转换程物理内存地址才能真正访问内存。为了提高这个转换效率,CPU会缓存最近的虚拟内存地址和物理内存地址的映射关系,并保存在一个由CPU维护的映射表中。为了...

1. 引子

系统进程是通过虚拟地址访问内存,但是CPU必须把它转换程物理内存地址才能真正访问内存。为了提高这个转换效率,CPU会缓存最近的虚拟内存地址和物理内存地址的映射关系,并保存在一个由CPU维护的映射表中。为了尽量提高内存的访问速度,需要在映射表中保存尽量多的映射关系。

而在Linux中,内存都是以页的形式划分的,默认情况下每页是4K,这就意味着如果物理内存很大,则映射表的条目将会非常多,会影响CPU的检索效率。因为内存大小是固定的,为了减少映射表的条目,可采取的办法只有增加页的尺寸。 

2. HugePages简介  2.1 相关概念

HugePages是在Linux2.6内核被引入的,主要提供4k的page和比较大的page的选择。 

概念

概念说明

page table

page table是操作系统上的虚拟内存系统的数据结构模型,用于存储虚拟地址与物理地址的对应关系。

当我们访问内存时,首先访问page table,然后Linux在通过page table的mapping来访问真实物理内存(ram+swap)

TLB

A Translation Lookaside Buffer (TLB)

TLB是在cpu中分配的一个固定大小的buffer(or cache),用于保存page table的部分内容,使CPU更快的访问并进行地址转换。

hugetlb

hugetlb 是记录在TLB 中的条目并指向Hugepages。

hugetlbfs

这是一个新的基于2.6 kernel之上的内存文件系统,如同tmpfs。

在TLB中通过hugetlb来指向hugepage。这些被分配的hugepage作为内存文件系统hugetlbfs(类似tmpfs)提供给进程使用。

 

2.2 使用HugePages的意义

HugePages是Linux内核的一个特性,使用hugepage可以用更大的内存页来取代传统的4K页面。使用HugePage主要带来以下好处:

1. HugePages 会在系统启动时,直接分配并保留对应大小的内存区域。

2. HugePages 在开机之后,如果没有管理员的介入,是不会释放和改变的。

3. 没有swap。

Notswappable: HugePages are not swappable. Therefore thereis no page-in/page-outmechanism overhead.HugePages are universally regarded aspinned.

4. 大大提高了CPU cache中存放的page table所覆盖的内存大小,从而提高了TLB命中率。

进程的虚拟内存地址段先连接到page table然后再连接到物理内存。所以在访问内存时需要先访问page tables得到虚拟内存和物理内存的映射关系,然后再访问物理内存。

CPU cache中有一部分TLB用来存放部分page table以提高这种转换的速度。因为page size变大了,所以同样大小的TLB,所覆盖的内存大小也变大了。提高了TLB命中率,也提高了地址转换的速度。

5. 减轻page table的负载。

进行XXX系统性能测试时,如果没有使用HugePages,数据库服务器上的pagetable大小大约为5G(这应该也是导致性能测试时数据库服务器内存不足的主要原因):

node74:/home/Oracle # cat /proc/meminfo

MemTotal:      16323732 kB

PageTables:     

配置了HugePages后,pagetable大小仅为124M(性能测试时内存使用率稳定在80%左右):

node74:/home/oracle # cat /proc/meminfo

MemTotal:      16323732 kB

PageTables:     

Eliminated page tablelookup overhead: 因为hugepage是不swappable的,所有就没有page table lookups。

Faster overall memory performance:  由于虚拟内存需要两步操作才能实际对应到物理内存地址,因此更少的pages,减轻了page table访问热度,避免了page table热点瓶颈问题。

6. 提高内存的性能,降低CPU负载,原理同上

 

2.3 使用HugePages需要注意的地方

1. Hugepages是在分配后就会预留出来的,其大小一定要比服务器上所有实例的SGA总和要大,差一点都不行。

比如说Hugepages设置为8G,oracle SGA为9G,那么oracle在启动的时候就不会使用到这8G的Hugepages。这8G就浪费了。所以在设置Hugepages时要计算SGA的大小,后面会给出一个脚本来计算。

2. 其他进程无法使用Hugepages的内存,所以不要设置太大,稍稍比SGA大一点保证SGA可以使用到hugepages就好了。

3. 在meminfo中和Hugepage相关的有四项:

HugePages_Total:   4611

HugePages_Free:     474

HugePages_Rsvd:     467

Hugepagesize:      2048 kB

HugePages_Total为所分配的页面数目,和Hugepagesize相乘后得到所分配的内存大小。4611*2/1024大约为9GB

HugePages_Free为从来没有被使用过的Hugepages数目。即使oraclesga已经分配了这部分内存,但是如果没有实际写入,那么看到的还是Free的。这是很容易误解的地方。

HugePages_Rsvd为已经被分配预留但是还没有使用的page数目。在Oracle刚刚启动时,大部分内存应该都是Reserved并且Free的,随着oracle SGA的使用,Reserved和Free都会不断的降低。

HugePages_Free-HugePages_Rsvd 这部分是没有被使用到的内存,如果没有其他的oracle instance,这部分内存也许永远都不会被使用到,也就是被浪费了。

4. HugePages和oracle AMM(自动内存管理)是互斥的,所以使用HugePages必须设置内存参数MEMORY_TARGET / MEMORY_MAX_TARGET 为0。

 

3.  配置HugePages

 

3.1 修改内核参数memlock

修改内核参数memlock,单位是KB,如果内存是16G,memlock的大小要稍微小于物理内存。计划lock 12GB的内存大小。参数设置为大于SGA是没有坏处的。

以root用户登录两台数据库服务器,编辑limits.conf文件:

node74:~ # vi /etc/security/limits.conf

增加以下两行内容:

*  soft  memlock    12582912

*  hard  memlock    12582912

 

3.2 验证memlock limit

重新登录root和oracle用户,检查memlocklimit

node74:~ # ulimit -l

12582912

oracle@node74:~> ulimit -l

12582912

 

3.3 禁用AMM

如果使用11G及以后的版本,AMM已经默认开启,但是AMM与Hugepages是不兼容的,必须先disable AMM。禁用AMM的步骤如下:

 

3.3.1 关闭数据库实例

已oracle用户登录两台数据库服务器,通过sqlplus关闭2个数据库实例。

oracle@node74:~> sqlplus / as sysdba

SQL> shutdown immediate

 

3.3.2 创建pfile

以oracle用户登录其中一台主机,执行以下命令创建pfile:

oracle@node74:~> sqlplus / as sysdba

SQL> create pfile='/home/oracle/pfile.ora' fromspfile=’+DG_ORA/orcl/spfileorcl.ora’;

 

3.3.3 编辑pfile

编辑pfile,删除memory_max_target和memory_target参数:

oracle@node74:~> vi /home/oracle/pfile.ora

删除下面几行:

orcl1.memory_max_target=11114905600

orcl2.memory_max_target=11114905600

*.memory_max_target=0

orcl1.memory_target=11114905600

orcl2.memory_target=11114905600

*.memory_target=0

修改后保存文件。

 

3.3.4 创建spfile

执行以下命令创建spfile:

oracle@node74:~> sqlplus / as sysdba

SQL> create spfile='+DG_ORA/orcl/spfileorcl.ora'from pfile='/home/oracle/pfile.ora';

 

3.3.5 修改系统参数kernel.shmall

Kernel.shmall是系统一次可以使用的最大共享内存大小。单位是page(4KB)。禁用AMM后,需要修改系统参数kernel.shmall,该参数设置过小的话,可能会导致数据库启动失败ORA-27102(详见附录4.2)。

ORACLE建议将其设置为系统中所有数据库实例的SGA总和。例如SGA总和为9GB,则需要设置kernel.shmall=9*1024*1024/4=2359296。 

以root用户登录两台数据库服务器,编辑sysctl.conf文件。

node74:~ # vi /etc/sysctl.conf

修改kernel.shmall参数:

kernel.shmall = 2359296

执行sysctl –p使配置生效:

node74:~ # sysctl -p

 

3.3.6 启动数据库实例

以oracle用户登录两台数据库服务器,通过sqlplus启动2个数据库实例。

oracle@node74:~> sqlplus / as sysdba

SQL> startup

 

3.4 计算需要使用的hugepage页面大小

确保全部实例都已经启动(包括ASM) ,然后以root用户运行hugepages_settings.sh(脚本内容见附录4.1)去评估需要设置的Hugepages的大小。

node74:/home/oracle # ./hugepages_settings.sh

This script is provided by Doc ID 401749.1 from MyOracle Support

(http://support.oracle.com) where it is intended tocompute values for

the recommended HugePages/HugeTLB configuration forthe current shared

memory segments. Before proceeding with the executionplease make sure

that:

 * OracleDatabase instance(s) are up and running

 * OracleDatabase 11g Automatic Memory Management (AMM) is not setup

  (See Doc ID749851.1)

 * The sharedmemory segments can be listed by command:

    # ipcs -m

 Press Enter toproceed...

----直接按Enter键

Recommended setting: vm.nr_hugepages = 4611

 

也可以手工计算:

nr_hugepages>=SGA_Target/Hugepagesize

=9G*1024M/2M

=4608

取一个比4608稍大的值即可。

 

3.5 修改vm.nr_hugepages参数

以root用户登录两台数据库服务器,编辑/etc/sysctl.conf:

node74:~ # vi /etc/sysctl.conf

修改vm.nr_hugepages参数为上一步中计算出来的值:

vm.nr_hugepages = 4611

执行sysctl –p使配置生效:

node74:~ # sysctl -p

 

3.6 停止数据库实例,重启操作系统

停止所有数据库实例,重启操作系统。(理论上不需要重启操作系统,建议重启)

 

3.7 检查设置是否生效

系统重启后,启动全部的数据库,通过以下命令检查配置是否生效:

node74:~ # grep HugePages /proc/meminfo

HugePages_Total:   4611

HugePages_Free:    2394

HugePages_Rsvd:    2387

HugePages_Surp:       0

 

HugePages_Free< HugePages_Total则说明Hugepages已经生效,同时HugePages_Rsvd不为0。 

4.  附录  4.1 脚本hugepages_settings.sh

#!/bin/bash
#
# hugepages_settings.sh
#
# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
#
# 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
# 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. Before proceeding with the execution please 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.%dn",$1,$2); }'`
# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
# Initialize the counter
NUM_PG=0
# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | awk '{print $5}' | 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.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" ;;
*) echo "Unrecognized kernel version $KERN. Exiting." ;;
esac
# End

4.2 数据库启动报错ORA-27102

Upon startup of Linux database getORA-27102: out of memory Linux-X86_64 Error: 28: No space left on device

Subject:

Upon startup of Linux database getORA-27102: out of memory Linux-X86_64 Error: 28: No space left on device

Doc ID:

Note:301830.1

Type:

PROBLEM

Last Revision Date:

31-OCT-2008

Status:

PUBLISHED

In this Document

Symptoms

Changes

Cause

Solution

References


--------------------------------------------------------------------------------

Applies to:

OracleServer- Enterprise Edition - Version: 9.2.0.4 to 11.1.0.6

UnitedLinux x86-64

Red Hat Enterprise Linux Advanced Serverx86-64 (AMD Opetron Architecture)

x86 64 bit

Symptoms

When trying to increase the SGA to approachhalf available RAM with an Oracle 64bit version on a Linux 64bit operatingsystem, even though shmmax is set to match half the amount of  RAM, youget the following error when trying to start the instance:

SQL> startup nomount

ORA-27102: out of memory

Linux-x86_64 Error: 28: No space left ondevice 

Changes

shmall is too small, most likely is set tothe default setting of 2097152


$ cat /proc/sys/kernel/shmall

2097152

Cause

shmall is the total amount of sharedmemory, in pages, that the system can use at one time.

Solution

Set shmall equal to the sum of all the SGAson the system, divided by the page size. 

The page size can be determined using thefollowing command: 

$ getconf PAGE_SIZE

4096

For example, if the sum of all the SGAs onthe system is 16Gb and the result of  '$ getconf PAGE_SIZE' is 4096 (4Kb)then set shmall to 4194304 (4Mb)

As the root user set the shmall to 4194304in the /etc/sysctl.conf file:

kernel.shmall = 4194304

then run the following command:

# sysctl –p

# cat /proc/sys/kernel/shmall

4194304

NOTE:

The above command loads the new value and areboot is not necessary

Switch back to being the oracle user andretry the startup command.

References

Note 169706.1 - Oracle? Database onAIX?,HP-UX?,Linux?,Mac OS? X,Solaris?,Tru64 Unix? Operating SystemsInstallation and Configuration Requirements Quick Reference (8.0.5 to 11.1)

Keywords

NO~SPACE~LEFT~ON~DEVICE ; START~INSTANCE ;OUT~OF~MEMORY ; 64BIT ;


    
 
 

您可能感兴趣的文章:

  • tcmalloc内存泄露优化c++开源库下载,安装及使用介绍
  • redhat9内存使用率高达73%,怎么查看内存具体使用情况
  • linux下free命令显示的内存使用情况分析
  • 关于大于2G内存的使用.....按32位编译的进程怎么使用大于2G的内存?
  • 大家好,我想问下有人用过"linux进程的内存使用解析"中推荐使用的"Ben Maurer写的perl脚本"查看内存么
  • 共享内存一般是怎么使用的,是同消息队列配合使用么
  • solaris 8 下有没有返回系统总物理内存和当前所使用内存大小的函数。(不是top,vmstat命令)
  • 如何查看某个进程的cpu使用和内存使用情况????
  • 使用VWMARE安装linux的内存使用问题
  • 计算进程的内存使用量应该使用/proc/self/statm哪几个量相加表示?
  • 我的redhat linux7.3因为内存有些少,所以我想随时查看内存的使用情况该如何去做,还有我想关掉(而不是切换)图形界面应该用什么命令
  • 100分求解如何查看内存最高使用值!!
  • 内核不能使用虚拟内存?
  • 如何减少内存的使用。
  • 怎样才能配置XSERVER,让它能最少的使用资源??哪一个窗口管理器使用资源最少??为什么我的LINUX用掉了我80%的内存资源??????要我命呀!!!!!
  • Unix/linux下如何监测共享内存的使用情况
  • 怎么打开一个进程并得到这个进程内存使用的信息?
  • 请问在SOLARIS上怎么实时查看程序的内存使用状况??
  • top命令显示的内存使用量是如何得出的
  • linux如何限制指定进程的内存使用量?
  • linux下共享内存 函数shmat()的使用!
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • linux系统下使用使用性能监视工具的前提?
  • 性能测试中应该用top命令统计cpu使用情况还是ps命令?
  • 请教各位:只安装TOMCAT而不搭配apache一起使用,在性能上有什么差别
  • ********************使用io复用好还是多线程的性能好?**************************
  • Mysql自带profiling性能分析工具使用分享
  • 强制SQL Server执行计划使用并行提升在复杂查询语句下的性能
  • http://support.oracle.com iis7站长之家
  • 使用sqlbulkcopy提高导入数据的性能的方法
  • 【求助贴】数据库基准性能测试OSDL以及其工具的BDT系列的使用
  • mysql性能优化脚本mysqltuner.pl使用介绍
  • MySQL性能分析及explain的使用说明
  • 在Python中使用异步Socket编程性能测试
  • 在Nginx中使用X-Sendfile头提升PHP文件下载的性能(针对大文件下载)
  • 如何书写高质量jQuery代码(使用jquery性能问题)
  • MySQL索引背后的之使用策略及优化(高性能索引策略)
  • JAVA LinkedList和ArrayList的使用及性能分析
  • C++ I/O 成员 tellg():使用输入流读取流指针
  • 在测试memset函数的执行效率时,分为使用Cash和不使用Cash辆种方式,该如何控制是否使用缓存?
  • C++ I/O 成员 tellp():使用输出流读取流指针
  • 求ibm6000的中文使用手册 !从来没用过服务器,现在急需使用它,不知如何使用! 急!!!!!
  • Python不使用print而直接输出二进制字符串
  • 请问:在使用oracle数据库作开发时,是使用pro*c作开发好些,还是使用库函数如oci等好一些啊?或者它们有什么区别或者优缺点啊?
  • Office 2010 Module模式下使用VBA Addressof
  • 急求结果!!假设一个有两个元素的信号量集S,表示了一个磁带驱动器系统,其中进程1使用磁带机A,进程2同时使用磁带机A和B,进程3使用磁带机B。
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • c#中SAPI使用总结——SpVoice的使用方法
  • sharepoint 2010 使用STSNavigate函数实现文件下载举例
  • 使用了QWidget的程序,如何使用后台程序启动它?
  • 使用libpcap读取tcpdump抓取的文件并解析c代码实例
  • Jsp可否使用带有GUI的JavaBean,如何使用?
  • c/c++预处理命令预#,##使用介绍


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,