版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
OracleMemoryManagementandHugePage大家好,我是魏兴华,你们可以叫我肉丝,我的英文名是Rose。在这篇文章中,我给大家介绍一些Oracle到9I版本出现的PGA的自动管理,到10G版本出现的SGA自动管理(ASMM),再到11G版本出现的memory自动管理(AMM),Oracle基本是在朝着智能化、傻瓜化、自动化的方向稳步前进着,对于初学Oracle的DBA来说,看到这些不同的内存管理方式一定心里有着不同程度的疑惑,例如:Oracle有这么多内存分配的管理方式,我该使用哪一种?是使用11G版本推出的AMM管理方式,还是使用10G版本出现的ASMM管理方式?或者干脆使用最旧的手工方式管理内存?l什么情况下我该使用大页?为什么大页这个词最近几年这么容易听到?写这篇文章的初衷也来源于上面这些非常正常的疑问,如果这篇文章能给有这些疑惑的DBA朋友一些指导和帮助,那肉丝我也就真的功莫大写了。emory在一个运行着Oracle数据库的专用服务器上,内存基本上被以下内容所占用:lageTable文件系统CacheAOracle进程其他进程(RMAN,非Oracle的进程等等)严格来说OSPageTable也算是KernelMemory部分的内容,由于本文后面会重点讲大页的内容,因此把OSPageTable这部分在图中独立了出来,以引起读者注意。必须要强调,Oracle不应该使用掉主机上的所有内存,过量的内存分配会诱发操作系统SWAP的产生,导致Oracle性能严重降低,在RAC环境下,内存不足还使用特点做好规划和设计,以防出现OS内存不够用的情况。内存自动化发展历程我们首先了解一下Oracle内存发展的历程,基本上Oracle的内存管理在版本的演进过程中沿着越来越智能化、自动化、傻瓜化的方向前进。接触过MYSQL等数据库的DBA朋友应该比较清楚,这些数据库基本上都还需要DBA去决定每个内存组件的大小,而Oracle已经从9I版本开始就迈向智能化、自动化的过程了。下图是Oracle内存管理的一个演进图:PGA自动管理创建一个独立的操作系统进程来为用户提供服务,这个进程叫做服务器进程或者影子进程,它像是用户的一个代理,来操作数据文件或者SGA内存,由于服务器进程的代码是Oracle公司开发的,所以Oracle公司完全相信这些进程或代码是安全的,因此这些进程可以直接操作数据文件和SGA内存,这些进程接受用户进程发送的指令,并完成相关的操作,并根据需要来给用户进程返回结果。由于服务器进程是操作系统上的一个进程,因此它本身需要占用一些操作系统内存,除此之外,进程在对数据进行读取、排序、hash过程中,也会占用一定量的内存,在Oracle9I版本之前,对于服务器进程的内存管理是由一些参数去控制的,以下参数代表每一个服务器进程可以使用的不同区域的内存大小(都是进程的私有内存区域):SORT_AREA_SIZEHASH_AREA_SIZEBITMAP_MERGE_AREA_SIZECREATE_BITMAP_AREA_SIZE程可用的hash区大小,这些参数都有默认值,但是默认值是否合适,需要打上一个大大的问号,因为不同的任务对于PGA内存的不同区域有不同的要求,例如,如果是做排序操作,就对排序区内存要求较大,而对hash如果默认值不合适,DBA可以手工调整这些区域的大小。Oracle9I版本出现了PGA的自动管理,不再需要像9I之前版本需要设置一系列参数来控制PGA的使用,只需要设置PGA_AGGREGATE_TARGET为一个值,就可以控制所有的服务器进程的PGA使用量,至于每个服务一般情况下对于PGA的大量使用有如下几种操作:hash对于hashjoin操作,hash桶所占用的内存就在进程的私有PGA内存中,而不是在共享内存SGA中,如果使用PGA手工管理的话,可以通过HASH_AREA_SIZE参数来动态调整会话进行hash操作能够。sort对于排序操作,例如查询语句里的orderby、创建索引的排序操作等占用的内存也在PGA中,如果使用PGA手工管理,可以通过SORT_AREA_SIZE参数动态调整会话排序操作可以使用的内存量。parallel并行操作简直可以说是PGA内存的杀手,每一个并行进程都能使用到最多2G的PGA内存,当然Oracle会确保所有的并行slave使用的PGA内存不能超过PGA_AGGREGATE_TARGET的一半。现在Oracle的版本已经出到了12C,PGA的自动管理已经发展了很多个年头,如果是个人,也应该是一个非常成熟的小伙子了,甚至是位大叔了,绝大部分数据库操作完全没必要再去手工调整PGA的一些参数。不过,我们依然能从互联网上、论坛上看到有很多DBA对这种手工调整PGA的技术崇拜有加(我以前也是),确实在一些情况下,通过手工调整PGA的相关内存区,可以达到加速排序等一些操作的目的,但是如果需要操作的数据量非常的大,那这种调整往往是费时费力,甚至是徒劳的,因为对于一个进程的私有PGA内存来说,像sort,hash等P区域的内存分配是有限制的,现在11GR2的版本对于每个进程的PGA内存最大限制默认就非常的徒劳,甚至还可能变慢(肉丝亲身遭遇过变慢的案例)。是否使用PGA自动管理由参数为PGA手工管理,回到9I之前的使用方式。这里肉丝提供几个大家可能会感兴趣的隐含参数,比如我上面提到了每个进程最大能使用的PGA不能超过2个G,通过修改隐含参数可以突破这个限制。肉丝在这里警戒各位,这些参数如果要在生产环境使用,请在你的数据库版本下做好测试。以下为11GR2版本的情况,其他版本并未做测试:KB_SMM_PX_MAX_SIZE所有并行查询的SLAVE进程能够用到的PGA总量。默认值为1/2pgaaggregatetargetKBRAC节点都可以用到这么多内存。以上全部为动态参数,可以在session/system级别来在线修改。alteraltersystemset"_SMM_PX_MAX_SIZE"=10485760;altersystemset"_SMM_MAX_SIZE"=1048576;altersystemset"_PGA_MAX_SIZE"=2147483648;321上面的参数调整后,一定要设置对应的pga_aggregate_target,否则以上调整可能会不起作用,建议设置为修改后的_SMM_PX_MAX_SIZE的值的两倍。默认情况下,每个进程使用的排序区不能超过1G。由参数_SMM_MAX_SIZE(单位KB)控制,默认为_PGA_MAX_SIZE(单位B)的一半。例如,并行度20创建索引,总共可以使用的排序区大小为20*1G=20G,但是同时还受参数_SMM_PX_MAX_SIZE的控制,所有的slave占用的内存不能超过_SMM_PX_MAX_SIZE的值(单位为KB),默认为pga_aggregate_target的一半。同时64位系统下,每个进程可以使用的排序空间不能超过4个G。所以即使把_SMM_MAX_SIZE调整大于4个G也没有用。_SMM_PX_MAX_SIZE,所有并行查询的SLAVE进程能够用到的PGA总量。每个RAC节点都可以用到这么多,限制的是本节点所有并行slave能够消耗的PGA。PGA_AGGREGATE_TARGET的设定经常是一个摸索的过程,这里给出官方的一个分配指导原则PGAPGA_AGGREGATE_TARGET=(TOTAL_MEM*80%)*20%foranOLTPsystemPGA_AGGREGATE_TARGET=(TOTAL_MEM*80%)*50%foraDSSsystem12上面公式中的TOTAL_MEM*80%代表着Oracle可以使用的所有内存为操作系统的80%,再根据不同类型业50%。这个只是一个指导的意见,具体情况要具体分析。例如,你的OLTP系统上有成千上万个连接,那么你可以粗略的按照每个进程占用10M的内存来大体的计算一下PGA需要占用的内存空间,再者,假如你的系统不但连接数非常多,而且活跃的连接数也非常的多,那么你可以按照每个进程至少12M的内存来进行估算,更为重要的,系统中假如存在非常多的临时性的计算任务,那么要为PGA预留的内存就更多了。例如,并行度设置为5创建索引,每个并行进程占用的PGA内存接近1个G:12356789(selectPGA_USED12356789(selectPGA_USED_MEM/1024/1024,PGA_ALLOC_MEM/1024/1024,PGA_MAX_MEM/1024/1024fromv$processorderby1desc)whererownum<14;selectselect*from44PGAPGA_USED_MEM/1024/1024PGA_ALLOC_MEM/1024/1024PGA_MAX_MEM/1024/10241041043.707791044.396731044.39673904.904.724821905.334227905.334227851851.350813851.959227851.959227804804.526175805.146727805.146727589589.681547590.209227637.58422727.27.068662627.537992527.537992527.27.068662627.537992527.5379925所以你在为系统规划PGA内存时不要忘了这些临时性任务需要占用的内存。他们可能是很大的一块贼。该为数据库分配多少的PGA内存,除了把连接数的多少这个指标作为一个考量因素外,还需要关注活跃连接数的多少,这是因为很多系统连接数虽然非常的多,但是去数据库里一统计发现,绝大部分的连接已经几个小时甚至几天都没活跃过了,这往往是应用程序的连接池不加以管理的结果(也可能是其他原因)。对于不照每个15M-20M计算。这里再提供一种估算每个空闲的服务器进程占用OS内存的方法。首先通过操作系统命令free-m查看一下当11echoecho3>/proc/sys/vm/drop_caches2233##free-m44totalusedfreesharedbufferscached5512892369590593320422766-/+buffers/cache:693585956477Swap:15999127614723然后创建2000个连接12345679#!/bin/sh./home/Oracle/.bash_profile12345679#!/bin/sh./home/Oracle/.bash_profilestep=1while[$step-lt2000]donohupsqlplustest/test@test.sql&let"step+=1"echo$stepdoneL_Nnumber;/end;dbms_lock.sleep(600);begintesttest.sqldeclare88再次查看剩余的操作系统内存,通过没创建连接之前的剩余内存减去创建完2000个连接之后的剩余内存可以估算出每个进程占用的内存大约为(59332-44548)/2000=7Mfreefree-mbuffers-/+buffers/cache:840994482314723cachedsharedtotalusedfreeSwap:128923445488437415999127626311043251读者需要牢记,减少的7M内存中,绝大部分都是进程本身占用的,只有1-2M的内存是PGA占用的。因此上MPGA确认一个空闲进程占用的真正PGA内存有多大,可以通过v$process视图中PGA_ALLOC_MEM字段来获得,如下:只有1.49M。但是就像上面已经提到的,这个进程从操作系统层面看却占用了7M左右的内存。selectselectround(PGA_ALLOC_MEM/1024/1024,2)fromv$processwherespid=5553;2ROUND(PGA_ALLOC_MEM/1024/1024,2)1.494351pga_aggregate_target参数指定的值并不是一个硬限制,直到Oracle12C才提供了一个参数来强制限制PGA的使用量。如果读者不知道该为自己系统的PGA设置一个什么样的值,可以通过视图v$pgastat中的maximumPGAallocated,totalPGAallocated值作为参考,前者代表自实例启动以来最大的PGA使用峰值,后者代表当前PGA的使用量,不过这个视图最大的缺点是不能看到各个时间段的PGA总体使用情况,这里肉丝给大家提供一个更好的视图来作为参考v$sysmetric_history11selectselectbegintime,endtime,value22fromfromv$sysmetrichistory33wherewheremetric_name='TotalPGAAllocated';44556BEGINBEGIN_TIME7722016-04-0811:31:212016-04-0811:32:213237468168822016-04-0811:30:202016-04-0811:31:213237468169922016-04-0811:29:212016-04-0811:30:2032840499222016-04-0811:28:212016-04-0811:29:2132374681622016-04-0811:27:212016-04-0811:28:2132374681622016-04-0811:26:202016-04-0811:27:2132374681622016-04-0811:25:212016-04-0811:26:2032374681622016-04-0811:24:212016-04-0811:25:2132661196822016-04-0811:23:212016-04-0811:24:21323746816上面查询的输出代表了各个时间段的,PGA内存的使用量,结果集并没有完全列出来,读者可以根据PGA各个时间段的使用量来更加精准的去为自己系统的PGA如何做设定做决策。设定PGA的过程是一个循序渐进的过程。再次强调,一个进程占用的内存除了PGA之外,进程本身也会占用内存,这点上面我们已经讨论过。PGA_AGGREGATE_TARGET设定值的三倍,这里你听一下就行了,不必当真。如果生产环境真的遭遇了PGA严重使用过量的情况,可以通过Event10261来限制某个/所有进程PGA的使11altersessionsetevents'10261tracenamecontextforever,level100000';一旦进程超出PGA的设定配额,会被后台进程杀掉并报错,不同的版本可能报错的信息不一样:Forand+,ORA-10260For11.1-,ORA-600[723]12CPGA_AGGREGATE_LIMIT12C之前的版本对于PGA的使用限制并没有一个硬限制,这个可能会导致一些问题,比如不加以限制后可能会导致OSSWAP的问题,一旦出现SWAP会导致Oracle性能的急剧下降,甚至导致DOWN机,我曾经遭遇SWAPLGWR了SWAP,数据库系统的表现是几乎完全HANG死,最后没办法只能重启解决问题。对于这个新特性的使用是通过参数PGA_AGGREGATE_LIMIT来限制PGA的使用上线,它是一个推导参数,在使用ASMM情况下,取以下的最大值2GB200%PGA_AGGREGATE_TARGET3MB*PROCESSES在使用AMM情况下,肉丝还未找到PGA_AGGREGATE_LIMIT取值的规律,如果你知道,请告诉我贼。MSMM10G前SGA的管理是通过手工设置一系列的参数来实现的,例如重要的参数有以下几个:buffer_cache_sizeshared_pool_sizelarge_pool_sizestream_pool_sizelogbufferSGA是一大块内存的统称,由上面列出的组件组成,10G之前的版本,DBA需要对SGA的各个内存区域进行手工设置,这可能对一个DBA无形中要求变得非常的高,需要了解业务,了解热点数据量,了解SQL的使用方式,是否存在大量不同文本的SQL等等来决策来给每个区域分配多少内存。使用过这个版本的DBA基本都遭遇过一个经典的报错:ORA-04031,一般是由于sharedpool内存不够导致,这个不够的原因可能有很多,共享池内存的严重碎片化,大量的硬解析,巨大的PL/SQL文本等等都可能会导致这个问题。下面我们来看下,手工管理SGA情况下,如何考虑为buffercache和sharedpool这两个最重要的内存组件分配内存。BufferCacheBufferCache俗称数据块高速缓存,是用来缓存数据块的拷贝的,Oracle通过改进后的LRU算法以期待这些数据块后续被高效的重用。服务器进程从磁盘读入的数据就放在这块内存中,修改数据时,也是在这个区域对数据进行修改。并没有一个给buffercache分配内存的黄金法则,还是要根据操作系统的内存大小,业务的热点数据量、业务的类型等因素来决定给buffercache分配多大的内存大小。我们先看下如何决定整个SGA的大小,对于SGA的分配原则,官方建议如下:SGASGA=(TOTAL_MEM*80%)*80%foranOLTPsystemSGA=(TOTAL_MEM*80%)*50%foraDSSsystem12上面的公式格式跟PGA的公式大同小异,刨去20%内存给操作系统之后,分为了不同的系统类型,基本上是粗略了解是否给buffercache分配了足够的内存。但是熟悉我的朋友都知道,我是OWI方法论的践行者,对于命中率的崇拜在Oracle里已然不应该再存在,但是命中率作为一种性能诊断的辅助手段依然具有它的价值。如果系统的SQL都足够优化后,命中率不高,一定程度上意味着可能buffercache给小了或者你的业务访问的数据非常的离散,热点数量太少。这里肉丝给出的优化思路是自顶向下,命中率低是一个表象,最上层的应大buffercache来提升性能,加大之后还是不行,是不是要考虑增加系统内存来进一步提高buffercache的大小,最后是不是需要为数据库多加几个盘或者使用SSD来提高性能。采用自顶向下的分析方法有利于真正发现问题所在而且以最低的代价解决问题,如果仅仅是一个SQL由于缺少索引而导致整个数据库系统缓慢,DBA直接就去加盘扩容IO,那么最终会发现花费了这么大的代价,治标不治本,问题依然没有解决。上面给出的公式并不适用于所有情况,特别是OLTP系统,如果进程数非常的多,那么需要进一步降低SGA占用内存的比例,以预留出更多内存给PGA使用。SharedPoolOracle占用量最大的两块内存除了buffercache区就是SharedPool的内存了,它的结构非常的复杂,而且由于要缓存SQL代码这种非标准大小的文本,经常会产生大量的碎片化内存,sharedpool总体上包含了两大部分,一块是librarycache区,用来缓存SQL、PL/SQL代码,保存它们的执行计划,提高SQL的解析效率,如果你的应用代码从来不使用绑定变量,那么这一块的内存对你来说是一个很大的负担,但是Oracle里是无法关闭librarycache区的,因此对于OLTP系统,请确保SQL都使用了绑定变量。第二大块区域是rowcache区,用来缓存数据库的数据字典,由于保存在里面的信息是以行的形式存在,因此叫rowcache。对于这一块的内存,依据数据库中元信息(metadata)的多少而决定,如果数据库中有几十万的对象,那么这一块的内存就会占用比较大,同时表上的很多列都有直方图信息,也会导致这一区的内存占用比较大。在一个稳定的系统中,这一区域的内存基本上是静态的,Oracle中几乎没有操作会频繁修改rowcache区。有个例外情况是没有cache属性的sequence,如果这种sequence调用频繁,就会触发频繁的修改sequence的属性值,进而可能会产生rowcachelock的一些等待,优化的办法是为每一个sequence设置足够的cache值。如果应用程序没有使用绑定变量,而且难以修改,可以通过设置cursor_sharing为force来尝试解决问这里肉丝再讲一个亲身经历的案例,老DBA嘁,可能技能已经不多,但故事还是有的,曾经帮一位客户解决了一个freebufferwaits的案例,这个等待事件的出现一般说明buffercache过小,或者全表扫描、写入操作AWRfreebufferwaits排在TOPEVENT的第一名,占用的DBTIME已达到了百分之七八十,而且从awr报告中发现客户的sharedpool内存占用已经达到了接近50G,而分析数据库一个月之前的AWR报告,sharedpool的内存只有3个G左右的大小,基本上可以认定为sharedpool内存占用过大,而导致buffercache不够用,进而出现了freebufferwaits等待事件,经过跟客户沟通后知道,以前一直比较稳定,最近做过的大的变更是给数据库使用了oracle的flahcache,通过MOS上搜索flashcache关键字最终发现,在,OracleRAC如果使用了flashcache,那么会在sharedpool中分配额外的内存存放GCSbufferblocksDBA如果你打算使用Oracle的FlashCache那么请为它预留出足够的sharedpool内存。ASMM10G版本Oracle推出了ASMM,自动SGA管理,它的出现一定程度上帮助DBA解决了管理SGA的问题,通过设置参数sga_target为非0值来启用ASMM。但是在10GR1,包括10GR2的早期版本,ASMM还不够成熟存在比较多的BUG,导致了比较多的问题,所以当时DBA在一些核心的生产环境,还是沿用了9I时候的手工SGA管理。自动SGA管理,不再需要为每个内存组件设定值,当然如果你设置sga_target的同时,设置了db_cache_size这些参数,那么db_cache_size这些参数值会作为最小值要求。sgatargetmemory_target也为0,则回归到传统的MSMM管理。通过使用ASMM可以很大程度上解决上面提到的ORA-04031的错误。在使用了ASMM后,去查看spfile文件,会发现多了一些双下划线打头的内存参数如__db_cache_size,这些内存参数是Oracle实例运行过程中动态产生固化到spfile中的,如果实例运行的时间足够长,这些参数的值被固话后,相当于有了一个基于自身环境的最佳实践参数,数据库实例重启后,会沿用固化在spfile中的这些参数值。移动,这是11G的新Linux特性,通过参数_memory_imm_mode_without_autosga来控制。11G版本即使sga_target移动,这是11G的新Linux特性,通过参数_memory_imm_mode_without_autosga来控制。GranuleASMM技术的实现,内部是通过Granule在内存组件之间移动来实现。这里对Granule做一点解释,Oracle10G引入的自动共享内存管理,目的是为了解决下面的问题,“我应该把db_cache_size设置为多大?我应该把帮你搞定“。简单来说,就是通过比较通过增加数据块缓存减少的磁盘IO时间与通过增加共享池优化而节省的时间,通过比对,来得出是否需要在两者间来移动内存。为了让内存在db_cache_size和shared_pool_size之作系统、Oracle版本以及SGA大小的不同而不同,读者可以通过如下的SQL语句来查看当前实例的Granule的syssys@OLTP6>selectbytesfromv$sgainfo2wherename='GranuleSize';33355443264251inOracleDatabaseindicatesthatthegranulesizeincreasesfrom64MBto128MBwhentheSGA_TARGETparameterissetto1bytegreaterthan32G,andjumpsto256MBwhentheSGA_TARGETparameterissetto1bytegreaterthan64G.Agranulesizeof32MBispossiblewhentheSGA_TARGETwassettoavaluebetween8G+1byteto16G.AMM管理,由于使用了AMM后就不能使用大页,因此这个功能其实一直没被广泛使用,通过这个功能DBA只需要设置memory_target一个参数就可以完成整个数据库实例内存的配置,就像ASMM导致了一些双下划线隐含__sga_target。而且在版本之前,DBCA建库默认就是AMM管理(有些时候Oracle胆子真的是很大),以后开始DBCA建库时会检测操作系统内存大小,大于4G内存默认为ASMM,小于4G内存默认为AMM。同样如果你设置AMM后,也设置了SGA_TARGET等参数,那么这些参数会作为最小值要求。AMM最大的问题是不能使用大页内存。关于使用大页的重要性会在本文后面部分详细介绍。Doc749851.1Doc1453227.1.11G后由于出现了AMM,如果你做DBA时间足够长,你一定遇到过下面这个错误ORAORA-00845:MEMORY_TARGETnotsupportedonthissystem1这个错误给人莫名其妙的感觉,“MEMORY_TARGET特性不被支持”,其实不是特性不被支持,这是由于AMM使用的是操作系统的共享内存文件系统,位于/dev/shm下,如果配置的内存文件系统比较小,小于了memory_target的值就会报错,一般在Linux主流的操作系统上,这个内存共享文件系统的值是内存大小的一半,如果读者遭遇了这个问题,要不去调小memory_target的参数值,要不通过如下办法去修改这个共享内##umounttmpfs#mount-ttmpfsshmfs-osize=1200m/dev/shm3编辑/etc/fstab文件5tmpfs/dev/shmsize=1200mtmpfs006421大部分的环境里都是足够的。使用了ASM后,数据库实例的shared_pool内存需要重新评估计算,如下公式是在正常sharedpool的基础上SELECTSELECTSUM(bytes)/(1024*1024*1024)FROMV$DATAFILE;2SELECTSUM(bytes)/(1024*1024*1024)FROMV$LOGFILEa,V$LOGbWHEREa.group#=b.group#;5SELECTSUM(bytes)/(1024*1024*1024)FROMV$TEMPFILEWHEREstatus='ONLINE';64371如果ASM磁盘组是externalredundancy,需要在2MB基础上,每100G的空间,增加1MB。如果ASM磁盘组是normalredundancy,需要在4MB基础上,每50G的空间,增加1MB。如果ASM磁盘组是highredundancy,需要在6MB基础上,每33G的空间,增加1MB。ASM&SharedPool(ORA-4031)(文档ID437924.1)大页的原理于类Linux系统,CPU必须把虚拟地址转换程物理内存地址才能真正访问内存。为了提高这个转换效率,CPU会缓存最近的虚拟内存地址和物理内存地址的映射关系,并保存在一个由CPU维护的映射表中,为了尽量提高内存的访问速度,需要在映射表中保存尽量多的映射关系。这个映射表在Linux中每个进程都要持有一份,如果映射表太大,就会大大降低CPU的TLB命中率,主流的Linux操作系统,默认页的大小是4K,对于大内存来说,这会产生非常多的pagetableentries,上面已经提到,Linux下页表不是共享的,每个进程都有自己的页表,现在随便一个主机的内存都配置的是几十个G,几百个G,甚至上T,如果在上面跑Oracle不使用大页,基本上是找死,因为Oracle是多进程架构的,每一个连接都是一个独占的进程,大内存+多进程+不使用大页=灾难,肉丝在8年的DBA生涯里,至少帮助不下5个客户处理过由于没有使用大页而导致的系统故障,而这5个客户都是近三四年遇到的,为什么大页这个词提前个三五年并没有被频繁提起,而当下,大页这个词在各种技术大会,最佳实践中成为热门词汇?这是因为最近几年是Linux系统被大量普及应用的几年,也是大内存遍地开花的几年,而且现在一个数据库系统动不动就是几百上千个连接,这些都促成了大页被越来关注到。大页的好处我们来看一下使用了大页的好处:少的pagetableentries,减少页表内存pin住SGA,没有pageout提高TLB命中率,减少内核cpu消耗在没有使用大页的系统上,经常可能会发现几十上百G的页表,严重情况下,系统CPU的sys部分的消耗非常大,这些都是没使用大页的情况下的一些症状。大页的特点/缺点要预先分配不够灵活,甚至需要重启主机如果分配过多,会造成浪费,不能被其他程序使用。大页的分配方法通过在文件/etc/f中增加vm.nr_hugepages参数来为大页设定一个合理的值,值的单位为2MB。或者通过echo一个值到/proc/sys/vm/nr_hugepages中也可以临时性的对大页进行设定。至于应该为大页设定多大的值,这个要根据系统SGA的配置来定,一般建议大页的总占用量大于系统上所有SGA总和+2GB。HugePagesonOracleLinux64-bit(文档ID361468.1),AIX页表共享,一般不用设置大页。以下的内容是基于32位的系统,4K的内存页大小做出的计算:1)目录表,用来存放页表的位置,共包含1024个目录entry,每个目录entry指向一个页表位置,每个目录entry,4b大小,目录表共4b*1024=4K大小2)页表,用来存放物理地址页的起始地址,每个页表entry也是4b大小,每个页表共1024个页表entry,因此一个页表的大小也是4K,共1024个页表,因此页表的最大大小是1024*4K=4M大小3)每个页表entry指向的是4K的物理内存页,因此页表一共可以指向的物理内存大小为:1024(页表数)*1024(每个页表的entry数)*4K(一个页表entry代表的页大小)=4G4)操作系统将虚拟地址映射为物理地址时,将虚拟地址的31-22这10位用于从目录表中索引到1024个页表中的一个,将虚拟地址的12-21这10位用于从页表中索引到1024个页表entry中的一个。从这个页表entry中获得物理内存页的起始地址,然后将虚拟地址的0-12位用作4KB内存页中的偏移量,那么物理内存页起始地址加上偏移量就是进出所需要访问的物理内存地址。由于32位操作系统不会出现4M的页表,因为一个进程不能使用到4GB的内存空间,有些空间被保留使用,比如用来做操作系统内核的内存。而且页表entry的创建出现在进程访问到一块内存的时候,而不是一开始就创页表内存计算系统下,一个进程访问1GB的内存,会产生1M的页表,如果是在64位系统,将会增大到2M。很容易SGA0G,有1500个Oracle用户进程,64位Linux的系统上,最大的页表占用内存打个百分之四五十的折扣,这是因为只有服务器进程访问到SGA的特定区域后,进程才需要把这一块对应的页表项加入到自己的页表中。0.3版本版本之前,如果分配的大页数量不足,那么Oracle启动过程中不会使用大页,转而使用小页,但是在版本后,Oracle在启动时同样会尝试使用大页,如果大页的数量不够,那么会把当前配置的大页使用完,不够的部分再从小页中去获取,这一行为实际上是通过Oracle的一个参数来控制USE_LARGE_PAGES,后面会对这个参数做详细解释。通过数据库实例的alert文件可以清楚的看到这一情135678***********************************************************GlobalRegionallocatedwith135678***********************************************************GlobalRegionallocatedwithLargepagesLargePagesize=2048KBLargePagesconfiguredsystemwide=512(1024MB)LargePagesunusedsystemwide=0(0KB)(allocincr16MB)priortothenextinstancerestartincreasethenumberofunusedLargePagesbyatleast892048KBLargePages(178MB)systemwidetoget100%oftheShared************************************LargePagesInformation*****************22TotalTotalSharedGlobalRegioninLargePages=1024MB(85%)44LargeLargePagesusedbythisinstance:512(1024MB)99TotalTotalSharedGlobalRegionsizeis1202MB.Foroptimalperformance,TotalSharedGlobalRegioninLargePages=1024MB(85%),代表只有85%的SGA被放在了大页中。RECOMMENDATION部分,建议你至少增加89个大页来让SGA完全放到大页中。USE_LARGE_PAGES这个参数用来控制数据库实例启动时,对于大页内存的使用行为。有3个值在版本之前,版本多了一个值auto:true默认值,尽可能使用大页,有可能有一些页在大页中,有一些在小页中,这种情况下通过操作系统命令ipcs-ma可能会看到内存分段(内存分段可能有多重情况都会导致,例如开启numa也可能会导致内)false不使用大页only选项代表强制使用大页,否则无法启动auto()在实例启动时,通过后台进程dismechoxxx>/proc/sys/vm/nr_hugepages来尽可能的使用大页以下代码为在参数设置为auto情况下alert的输出:1234689***********************************************************LICENSE_MAX_SESSION=0Large1234689***********************************************************LICENSE_MAX_SESSION=0LargePagesize=2048KBTimetakentoallocateLargePages=0.130804secLargePagesconfiguredsystemwide=1257(2514MB)LargePagesunusedsystemwide=0(0KB)(allocincr16MB)DISMstarted,OSid=11969StartingStartingOracleinstance(normal)************************************LargePagesInformation*****************ParameterParameteruse_large_pages=AUTO55TotalTotalSharedGlobalRegioninLargePages=2514MB(100%)77LargeLargePagesusedbythisinstance:1257(2514MB)lsls-loradism--rwsr-x---1rootoinstall109247Mar311:34oradism可以看到启动实例过程中,优先启动了DISM进程,通过这个进程来自动完成大页的配置。$Oracle_HOME/bin/oradism的权限也是root权限,因为如果是grid权限不能完成大页的配置echoxxx>/proc/sys/vm/nr_hugepages。TransparentHugepage从RedHat6,RedHat7,OL6,OL7SLES11和UEK2kernels开始transparenthugepage被默认开启,它允许后就分配好,根据OracleMOSDOC:1557478.1,transparenthugepage导致了很多的问题,建议将其关闭查看是否启用了transparenthugepagecat/sys/kernel/mm/transparent_hugepage/enabled[always]never[]内的值是当前启用的值,上面的输出说明启rubconftransparenthugepage11titletitleOracleLinuxServer(2.6.32-300.25.1.el6uek.x86_64)22rootroot(hd0,0)33kernelkernel/vmlinuz-2.6.32-300.25.1.el6uek.x866444rororoot=LABEL=/transparent_hugepage=never55initrdinitrd/initramfs-2.6.32-300.25.1.el6uek.x86_64.imgtransparenthugepagenever来讲transparenthugepage关闭。也可以通过开机启动后,echo相应的值到对应的文件来动态关闭transparenthugepage。rcrc.localechonever>/sys/kernel/mm/redhat_transparent_hugepage/defragechonever>/sys/kernel/mm/redhat_transparent_hugepage/enabled123OS层面查看大页使用情况1122334455catcat/proc/meminfoHugePages_Total:43000HugePages_Free:29493HugePages_Rsvd:23550Hugepagesize:2048kBHugePages_Total为所分配的页面数目,和Hugepagesize相乘后得到所分配的内存大小。43000*2/1024大约为84GB。HugePages_Free为从来没有被使用过的Hugepages数目。即使Oraclesga已经分配了这部分内存,但是如果没有实际写入,那么看到的还是Free的。这是很容易误解的地方。HugePages_Rsvd为已经被分配预留但是还没有使用的page数目。在Oracle刚刚启动时,大部分内存应该都ReservedFreeOracleSGAReserved和Free都会不断的降低。HugePages_Free–HugePages_Rsvd
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2022-2027年中国贝伐珠单抗行业市场全景评估及发展战略规划报告
- 箱变基础预制施工方案
- 保险服务品牌转让居间服务
- 4S店装修贷款协议
- 杭州市乒乓球馆租赁合同
- 湖北医药学院药护学院《新媒体运营与管理》2023-2024学年第一学期期末试卷
- 2025年度铁路轨道施工安全监管合同范本2篇
- 2025年度食品加工合同:原材料供应商与食品加工厂(2025版)3篇
- 2025年度融资租赁合同的租金支付方式3篇
- 2025年度运动服饰品牌授权与销售合同3篇
- 数学八下学霸电子版苏教版
- SQL Server 2000在医院收费审计的运用
- 《FANUC-Oi数控铣床加工中心编程技巧与实例》教学课件(全)
- 微信小程序运营方案课件
- 陈皮水溶性总生物碱的升血压作用量-效关系及药动学研究
- 安全施工专项方案报审表
- 学习解读2022年新制定的《市场主体登记管理条例实施细则》PPT汇报演示
- 好氧废水系统调试、验收、运行、维护手册
- 中石化ERP系统操作手册
- 五年级上册口算+脱式计算+竖式计算+方程
- 气体管道安全管理规程
评论
0/150
提交评论