Oracle Share Pool内部管理机制的示例分析
小编给大家分享一下Oracle Share Pool内部管理机制的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
Oracle Share Pool内部管理机制
SHARE POOL利用堆(HEAP)的内存管理方式管理,在物理上由多个内存区(EXTENT)组成,内存区又由多个不同大小的CHUNK组成。而CHUNK又有可重用和空闲之分,并且它们分别有LRU LIST、FREE LIST、RESERVED LIST串联起来。
堆管理
Shared Pool是利用堆内存管理方式管理的(KGH:Kernel Generic Heap).从Oracle 9i开始,可以有多个最高级堆(TOP-LEVLE HEAP),最高级堆可以分成多个副堆,副堆下面还拥有子堆。堆和副对结构基本相同。从物理上讲,一个堆由多个内存区已link list的形式连接组成。一个内存区物理上使用一个Granule,一个内存区由多个chunk组成,所以chunk是heap的最小内存单位。
Chunk的使用情况可由X$KSMSP内部视图查看。每个堆头上则包含了可使用的chunk列表和已使用的chunk列表。通过dump heap命令可以在trace文件中观察heap和extent的关系。
alter system set events 'immediate trace name heapdump level 2';
案例:
SQL>selectname,bytes/1024/1024fromv$sgainfo;NAMEBYTES/1024/1024-----------------------------------------------FixedSGASize1.27566528RedoBuffers5.59765625BufferCacheSize180SharedPoolSize104LargePoolSize4JavaPoolSize4StreamsPoolSize0SharedIOPoolSize0GranuleSize4MaximumSGASize498.875StartupoverheadinSharedPool52NAMEBYTES/1024/1024-----------------------------------------------FreeSGAMemoryAvailable20012rowsselected.[oracle@node1~]$more/u01/app/oracle/diag/rdbms/prod/prod/trace/prod_ora_14983.trcTracefile/u01/app/oracle/diag/rdbms/prod/prod/trace/prod_ora_14983.trcOracleDatabase11gEnterpriseEditionRelease11.2.0.1.0-ProductionWiththePartitioning,OLAP,DataMiningandRealApplicationTestingoptionsORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1Systemname:LinuxNodename:node1Release:2.6.18-194.el5Version:#1SMPTueMar1621:52:43EDT2010Machine:i686Instancename:prodRedothreadmountedbythisinstance:1Oracleprocessnumber:32Unixprocesspid:14983,p_w_picpath:oracle@node1(TNSV1-V3)***2014-07-0214:58:47.532***SESSIONID:(32.758)2014-07-0214:58:47.532***CLIENTID:()2014-07-0214:58:47.532***SERVICENAME:(SYS$USERS)2014-07-0214:58:47.532***MODULENAME:(sqlplus@node1(TNSV1-V3))2014-07-0214:58:47.532***ACTIONNAME:()2014-07-0214:58:47.532KGHLatchDirectoryInformationldirstate:2lastallocatedslot:99Slot[1]Latch:0x200065ecIndex:1Flags:3State:2next:(nil)Slot[2]Latch:0x3e75571cIndex:1Flags:3State:2next:(nil)......(省略)Slot[99]Latch:0x2002616cIndex:1Flags:3State:2next:0x1******************************************************HEAPDUMPheapname="sgaheap"desc=0x200010b4extentsz=0x7ad4alt=124het=32767rec=9flg=-126opc=0parent=(nil)owner=(nil)nex=(nil)xsz=0x0heap=(nil)fl2=0x60,nex=(nil)dsforlatch1:0x2002a9900x2002b5c80x2002c2000x2002ce38reservedgranulecount0(granulesize4194304)******************************************************HEAPDUMPheapname="sgaheap(1,0)"desc=0x2002a990extentsz=0xfc4alt=124het=32767rec=9flg=-126opc=0parent=(nil)owner=(nil)nex=(nil)xsz=0x400000heap=(nil)fl2=0x20,nex=(nil)latchset1of1durationsenabledforthisheapreservedgranulesforroot0(granulesize4194304)EXTENT0addr=0x3b800000Chunk3b800038sz=24R-freeable"reservedstoppe"Chunk3b800050sz=212888R-free""Chunk3b833fe8sz=24R-freeable"reservedstoppe"Chunk3b834000sz=3981312perm"perm"alo=3290272EXTENT1addr=0x3bc00000Chunk3bc00038sz=24R-freeable"reservedstoppe"Chunk3bc00050sz=212888R-free""Chunk3bc33fe8sz=24R-freeable"reservedstoppe"Chunk3bc34000sz=3510272perm"perm"alo=3510272Chunk3bf8d000sz=465920perm"perm"alo=465920Chunk3bffec00sz=5120free""EXTENT2addr=0x3c000000Chunk3c000038sz=24R-freeable"reservedstoppe"Chunk3c000050sz=212888R-free""Chunk3c033fe8sz=24R-freeable"reservedstoppe"Chunk3c034000sz=3850176perm"perm"alo=3850176Chunk3c3dffc0sz=131088perm"perm"alo=131088Chunk3c3fffd0sz=48free""EXTENT3addr=0x3c400000Chunk3c400038sz=24R-freeable"reservedstoppe"Chunk3c400050sz=212888R-free""Chunk3c433fe8sz=24R-freeable"reservedstoppe"Chunk3c434000sz=3980368perm"perm"alo=3980368Chunk3c7ffc50sz=944free""EXTENT4addr=0x3c800000Chunk3c800038sz=24R-freeable"reservedstoppe"Chunk3c800050sz=212888R-free""Chunk3c833fe8sz=24R-freeable"reservedstoppe"Chunk3c834000sz=3672700perm"perm"alo=3672700Chunk3cbb4a7csz=308240perm"perm"alo=308240Chunk3cbffe8csz=372free""
CHUNK
Chunk是以链条(chain)的方式存在于内存区,每个chunk包含header和body两部分,chunk的状态大体上可以分为free(可立即使用)、recreatable(可再生)、freeable(只有在session或call期间内保存必要的对象状态)、permanent(永久、不可再生)等,其中free和recreatable状态下的chunk可以重复使用。
FREE LIST
Free list主要用于管理空闲的chunk,并且是用bucket管理的。从Oracle 9i开始,一个heap总共255个bucket,bucket所包含的free chunk大小随bucket的编号增加而递增,个bucket下的free chunk已linked list的形式链接。
(1)获得shared pool latch在free list中查找合适大小的空闲chunk。如果在获取shared pool latch时发生了争用,则会出现latch:shared pool等待事件。这时Oracle会一直持有shared pool latch,直到获得所需的内存为止。所在内存碎片化比较严重的shared pool中,进程持有shared pool latch的时间也会相应变长。
(2)如果不存在合适大小的空闲chunk,则在查找到更大的空闲chunk后分割(split)使用,分割后剩下的内存区域则重新登记到free list中。分割内存意味着内存中的碎片开始增多。由于每个cursor所需内存的大小不同,所以shared pool的空闲内存不像buffer cache中的空闲内存一样具有固定大小。
(3)如果检索了free list也没有找到所有合适的空闲chunk,则检索lru list。lru list上的chunk是重建(recreatable)的,而且是当前不使用的(没有处于pin状态)。
(4)如果在lru list上也没有找到合适的chunk,且所请求的内存还没有达到隐含参数_shared_pool_reserved_min_alloc的阈值,则追加分配share pool中剩余的内存空间。
(5)如果以上请求的内存均失败,则出现ORA-4031错误
FREELISTS:Bucket0size=16Bucket1size=20Bucket2size=24Bucket3size=28Bucket4size=32Bucket5size=36Bucket6size=40Bucket7size=44Bucket8size=48Chunk3c3fffd0sz=48free""Chunk3ebfffd0sz=48free""Bucket9size=52Bucket10size=56Bucket11size=60Bucket12size=64Bucket13size=68Bucket14size=72Bucket15size=76Bucket16size=80Bucket17size=84Bucket18size=88Chunk3e7fffa8sz=88free""Bucket19size=92Bucket20size=96Bucket21size=100Bucket22size=104Bucket23size=108Bucket24size=112Bucket25size=116Bucket26size=120Bucket27size=124......
LRU LIST
Lru list主要保存着当前未使用而且可以重建的chunk。当会话在free list中找不到空闲的chunk时,在会在lru list中寻找。
UNPINNEDRECREATABLECHUNKS(lrufirst):Chunk3b1f4000sz=4096recreate"CCUR^3de2d7f5"latch=(nil)Chunk3a649000sz=4096recreate"CCUR^f5a8106a"latch=(nil)Chunk383b3000sz=4096recreate"CCUR^2b855a04"latch=(nil)Chunk383b1000sz=4096recreate"CCUR^f65cc3ed"latch=(nil)Chunk3ee4c524sz=332recreate"KGLHD"latch=(nil)Chunk3af76da8sz=4096recreate"SQLA^13df1501"latch=(nil)Chunk3a72e000sz=4096recreate"CCUR^13df1501"latch=(nil)Chunk39ff96e0sz=332recreate"KGLHD"latch=(nil)Chunk3a37e740sz=4096recreate"SQLA^7a9f4a60"latch=(nil)Chunk38330000sz=4096recreate"CCUR^7a9f4a60"latch=(nil)Chunk39f8732csz=332recreate"KGLHD"latch=(nil)Chunk3ab0dec4sz=4096recreate"SQLA^8005cf3c"latch=(nil)Chunk3a670000sz=4096recreate"CCUR^8005cf3c"latch=(nil)Chunk3ed28b1csz=1524recreate"KGLHD"latch=(nil)Chunk39cb0d20sz=332recreate"KGLHD"latch=(nil)Chunk3aaeb214sz=4096recreate"SQLA^63c15ff"latch=(nil)Chunk3a646000sz=4096recreate"CCUR^63c15ff"latch=(nil)Chunk39ff9a38sz=540recreate"KQRPO"latch=0x3ca28438Chunk3ee4c88csz=540recreate"KQRPO"latch=0x3ca28438Chunk3ee4caa8sz=540recreate"KQRPO"latch=0x3ca28438Chunk39fabd2csz=540recreate"KQRPO"latch=0x3ca28438Chunk39fabf48sz=540recreate"KQRPO"latch=0x3ca28438Chunk3ee481f8sz=540recreate"KQRPO"latch=0x3ca28438Chunk3ee48414sz=540recreate"KQRPO"latch=0x3ca28438Chunk3ee48630sz=540recreate"KQRPO"latch=0x3ca28438Chunk3a1a1228sz=4096recreate"KGLS^9b4819a8"latch=(nil)Chunk39b4a504sz=4096recreate"KGLS^6ccccfe"latch=(nil)Chunk3abf0fb4sz=4096recreate"KGLS^8db54da"latch=(nil)Chunk3aa65508sz=4096recreate"KGLS^e2d7481e"latch=(nil)Chunk3a2839d0sz=4096recreate"KGLS^8dd845ff"latch=(nil)Chunk3abd4f78sz=4096recreate"KGLS^f79d229a"latch=(nil)
RESERVED FREE LIST
Oracle 设置了保留内存区域,该区域用 Reserved free list管理。其大小由参数shared_pool_reserved_size决定(最小为5000字节,最大不能超过shared pool的50%)。
RESERVEDFREELISTS:Reservedbucket0size=16Chunk3dfffc14sz=980R-free""Chunk3dbffbe0sz=1032R-free""Reservedbucket1size=4400Reservedbucket2size=8204Reservedbucket3size=8460Reservedbucket4size=8464Reservedbucket5size=8468Reservedbucket6size=8472Reservedbucket7size=9296Reservedbucket8size=9300Reservedbucket9size=12320Reservedbucket10size=12324Reservedbucket11size=16396Reservedbucket12size=32780Reservedbucket13size=65548Chunk3b800050sz=212888R-free""Chunk3bc00050sz=212888R-free""Chunk3c000050sz=212888R-free""Chunk3c400050sz=212888R-free""Chunk3c800050sz=212888R-free""Chunk3cc00050sz=212888R-free""Chunk3d3cb8b8sz=214832R-free""Chunk3d400050sz=212888R-free""Chunk3e000050sz=212888R-free""Chunk3e400050sz=212888R-free""Chunk3e800050sz=212888R-free""Chunk3f000050sz=212888R-free""Reservedbucket14size=1990630Totalreservedfreespace=2558612UNPINNEDRECREATABLECHUNKS(lrufirst):Chunk3b1f4000sz=4096recreate"CCUR^3de2d7f5"latch=(nil)Chunk3a649000sz=4096recreate"CCUR^f5a8106a"latch=(nil)......
Oracle对进入reserved free list的对象大小有限制,即只有大于_shared_pool_reserved_min_alloc隐含参数阈值(默认值4400)的cursor才能进入到reserved free list。
SHARED POOL的SUB POOL技术
从Oracle 9i开始,shared pool可以分为多个sub pool,其数量受一下几个因素影响:
1、系统的CPU数量,默认情况下,在Oracle中每4个CPU分配一个sub pool,最多不能超过7个。
2、共享池的大小。sub pool的最小容量随着Oracle版本不同而不同。
9i ----- 128M(Minimum subpool size)
10g<10.2.0.3 ---- 256M
10.2.0.3 and higher ---512M
3、隐含参数_kghdisdx_count值
每个sub pool拥有独立的free list 、lru list和shared pool latch。从这个角度来讲,当系统拥有足够的内存和CPU时,将shared pool分为多个sub pool时能有效的减少shared pool latch的争用。
查看sub pool的数量:
kghlushrpool:=1:sharedpoolsubpools=0:javapoolSQL>selectcount(kghluidx)num_pools2fromx$kghlu3wherekghlushrpool=14/NUM_POOLS----------1SQL>showparametercpuNAMETYPEVALUE-----------------------------------------------------------------------------cpu_countinteger1
查看sub pool latch信息:
SQL>colnamefora40SQL>setlinesize120SQL>r1selectaddr,name,gets,misses,spin_gets2fromv$latch_children3*wherename='sharedpool'ADDRNAMEGETSMISSESSPIN_GETS------------------------------------------------------------------------------200A80FCsharedpool2100200A8098sharedpool2100200A8034sharedpool2100200A7FD0sharedpool2100200A7F6Csharedpool2100200A7F08sharedpool2100200A7EA4sharedpool493378707rowsselected.
查看sub pool 内存分配:
X$KSMSS([K]ernal [S]torage [M]emory Management [S]GA [S]atistics (lengths of SGA objects)
SQL>select2'sharedpool('||nvl(decode(to_char(ksmdsidx),'0','0-unused',ksmdsidx),'Total')3||'):'subpool,4sum(ksmsslen)bytes,round(sum(ksmsslen)/1048576,2)mb5fromx$ksmss6whereksmsslen>07groupbyrollup(ksmdsidx)orderbysubpoolasc;SUBPOOLBYTESMB--------------------------------------------------------------------------sharedpool(1):121639892116sharedpool(Total):121639892116
SQL>
Oracle 硬解析
1、获得shared pool latch ,从free list的bucket 中查找合适大小的free chunk。如果free list中的bucket list过长或者shared pool碎片化严重,那么在多个进程同时请求分配内存时,则会发生shared pool latch的争用。
2、如果不存在大小合适的free chunk,则分割较大的free chunk,分割后的free chunk重新挂载到适当大小的bucket下。如果不存在free chunk,则检索lru list。若在lru list中也不能获得合适大小的bucket,则从shared pool的剩余空闲内存中分配。如果cursor大小大于_shared_pool_reserved_min_alloc隐含参数设定的阀值,那么在reserved list中寻找free chunk。若果以上过程均失败,则出现ORA-4031错误。
3、若找到合适大小的chunk,则对cursor相应的handle(library cache handle)以exclusive 模式获得library cache lock,并创建LCO信息。在创建LCO信息后,library cache lock变换为null模式,然后以exclusive模式获得library cache pin,并创建执行计划等信息。硬解析成功后Oracle增加parse count(hard)统计值。
4、对sql cursor已shared模式获得library cache lock和library cache pin,并执行sql,这个阶段称之为执行阶段。
5、sql cursor执行结束后进入fetch阶段。在fetch阶段,sql cursor将library cache pin变为null模式,并释放library cache pin。
软软解析
由于在软解析过程中需要获得library cache latch,所以在高并发软解析的系统中,依然会出现与latch:library cache相关的等待事件,从而导致性能缓慢。
软软解析(Tom Kety)核心原理是通过设置session_cache_cursors参数将某个会话中常用的sql放入UGA的会话缓存区中,当会话发起相同的sql时,可以快速的从UGA取得cursor的信息,从而减少共享池的争用。当一个cursor被解析3次以上(包括3次)就会被放入到UG会话缓存区中。
案例:shared pool latch 争用
案例1:业务运行前:17:07:30SYS@prod>selectname,GETS,MISSESfromv$latchwhereupper(name)like'%LIBRARY%'ORupper(name)like'%SHARE%';NAMEGETSMISSES------------------------------------------------------------------------------------testsharednon-parentl000ksxpsharedlatch00kcfisstatssharedlatch00sharedpool12667661librarycacheloadlock00sharedpoolsimulator65760sharedpoolsimalloc450SharedB-Tree3020sharedserverconfiguration60sharedserverinfo10运行业务:17:08:34SCOTT@prod>begin17:08:382foriin1..100000loop17:08:523executeimmediate'insertintot1values('||i||')';17:09:184endloop;17:09:265end;17:09:276/PL/SQLproceduresuccessfullycompleted.业务运行后:17:11:05SYS@prod>selectname,GETS,MISSESfromv$latchwhereupper(name)like'%LIBRARY%'ORupper(name)like'%SHARE%'NAMEGETSMISSES------------------------------------------------------------------------------------testsharednon-parentl000ksxpsharedlatch00kcfisstatssharedlatch00sharedpool4526672214librarycacheloadlock00sharedpoolsimulator10864370sharedpoolsimalloc20480SharedB-Tree3160sharedserverconfiguration60sharedserverinfo1010rowsselected.17:15:42SYS@prod>selectsid,event,WAIT_TIME,statefromv$session_waitwheresid=42SIDEVENTWAIT_TIMESTATE-------------------------------------------------------------------------------------------------------42latch:sharedpool-1WAITEDSHORTTIMEElapsed:00:00:00.08案例2:业务运行前:17:18:35SYS@prod>selectsid,EVENT,TOTAL_WAITS,AVERAGE_WAITfromv$session_eventwheresidin(42,46);SIDEVENTTOTAL_WAITSAVERAGE_WAIT-------------------------------------------------------------------------------------------------42DiskfileoperationsI/O4.0342logfileswitch(privatestrandflushincomplete)110.0342logfilesync41.7642dbfilesequentialread385.2342latch:rowcacheobjects5.4442latch:sharedpool194.2542SQL*Netmessagetoclient24042SQL*Netmessagefromclient235318.942SQL*Netbreak/resettoclient2.0842eventsinwaitclassOther1046DiskfileoperationsI/O1.0346dbfilesequentialread33.0246SQL*Netmessagetoclient13046SQL*Netmessagefromclient1279.914rowsselected.运行业务:17:16:39SYS@prod>selectsid,usernamefromv$sessionwhereusernameisnotnull;SIDUSERNAME----------------------------------------1SYS42SCOTT46HR17:17:22SCOTT@prod>begin17:20:462foriin1..100000loop17:20:523executeimmediate'insertintot1values('||i||')';17:20:584endloop;17:21:025end;17:21:056/PL/SQLproceduresuccessfullycompleted.17:17:42HR@prod>begin17:21:162foriin1..100000loop17:21:243executeimmediate'insertintoscott.t1values('||i||')';17:21:494endloop;17:21:515end;17:21:526/PL/SQLproceduresuccessfullycompleted.业务运行后:17:22:32SYS@prod>selectsid,EVENT,TOTAL_WAITS,AVERAGE_WAITfromv$session_eventwheresidin(42,46);SIDEVENTTOTAL_WAITSAVERAGE_WAIT-------------------------------------------------------------------------------------------------42DiskfileoperationsI/O4.0342latch:cachebufferschains16.1842bufferbusywaits2.1542logfileswitch(privatestrandflushincomplete)110.0342logfilesync41.7642dbfilesequentialread413.2142latch:rowcacheobjects58.1342latch:sharedpool1008.1942librarycache:mutexX123.3342SQL*Netmessagetoclient24042SQL*Netmessagefromclient246044.4342SQL*Netbreak/resettoclient2.0842eventsinwaitclassOther87.0946DiskfileoperationsI/O3.0346latch:cachebufferschains13.2146bufferbusywaits1.3546latch:redocopy11.26SIDEVENTTOTAL_WAITSAVERAGE_WAIT-------------------------------------------------------------------------------------------------46dbfilesequentialread38.0246enq:HW-contention1.0146latch:rowcacheobjects58.1446rowcachelock1.0846latch:sharedpool666.1746librarycache:mutexX99.2946SQL*Netmessagetoclient13046SQL*Netmessagefromclient132010.6346eventsinwaitclassOther68.1426rowsselected.Elapsed:00:00:00.3717:22:42SYS@prod>17:22:02SYS@prod>selectsid,event,WAIT_TIME,statefromv$session_waitwheresid=4217:22:252orsid=46;SIDEVENTWAIT_TIMESTATE-------------------------------------------------------------------------------------------------------42latch:sharedpool-1WAITEDSHORTTIME46latch:sharedpool-1WAITEDSHORTTIME
看完了这篇文章,相信你对“Oracle Share Pool内部管理机制的示例分析”有了一定的了解,如果想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。