ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 探索系列——神人steve adams之著oracle8i interal service(十九)

探索系列——神人steve adams之著oracle8i interal service(十九)

原创 Linux操作系统 作者:wisdomone1 时间:2010-05-10 17:42:42 0 删除 编辑
       一些os专门为一些特定类型的segments保留某些虚拟地址范围.另外一些在虚拟地址空间范围的边界或极点(extremities)分配文本,数据,bss segments,
把极点之间的连续的未用地址空间范围留下来.堆和栈是在这个范围的对端上面进行分配的,是向中间方向进行增长的.其它一些segments,比如共享内存segments,必须
必须位于由程序本身指定stack和heap的一个位置.
       在这样的一些os中,有时有必要控制sga附加attached在哪个地址上,为了防止这些segments之间的地址空间冲突.在一些情况下,用shared_memory_address和hi_shared_memory_address
参数,但是一些其它的系统,在重新relink数据库前,有必要使用genksms和在ksms.s文件中修改附加地址.



intimate shared memory
       一个进程的虚拟地址空间中的每个segment,需要页表条目,用于支持虚拟到物理地址转变.如果2个以上的进程映射一个内存segment到它们虚拟地址空间的相同位置,从理论上说它们是可以共享相同的页表条目的.
  这也叫作亲密或私密共享内存.
       亲密共享内存在几个方面会提升性能.特别是,它极大增加了页表条目的tlb hit rate,因此减少了主内存的访问,较大程度加速了执行速度.对于需要大量共享内存和大量进程的实例,它会节省大量的页表内存.
       
       在一些os上,由于没有替代品,亲密共享内存会自动用于oracle.在一些情况下,因为os或硬件不支持所以它是不可用.但是,在一些情况下,它与_use_ism参数和共享内存segment大小有关.如果在支持精选程序
program-selectable的亲密共享程序,_use_ism等于true时,oracle会使用一个标记来从os的它的共享内存segments中请求亲密共享内存.但是,在一些os下,亲密共享内存只有在segment的页表具有精确的页面个数时才可用,
如果这样的话,会自动使用.比如,对于一个32 bit地址空间和一个4kb的内存页面大小,页表一个页面可以定址4mb内存.在这种情况下,如果使用了亲密共享内存,共享内存segment必须是4mb的倍数.这样就可以确保尽量小的调
整shared_pool_size,db_block_buffers,log_buffers参数,然后用oradebug ipc命令检查sga segments的大小.

       更进一步优化地址变化操作,就是允许使用更大尺寸的内存页面大小.比如,你可能使用chatr请求一个针对特定执行程序的用于数据或指令segments的较大的页面大小.使用一个大页面减少每个segment所需要的页表条目数量,
因而提升或加大了segment的tlb hit rate,同时减少了tlb load.oracle在内存页面大小有一些内置的依赖限制,因此请和oracle支持联系,在尝试这样作之前,使用一个大点的页面大小是否安全.













sga allocation
        当启动一个oracle实例,主要的sga区域大小首先根据初始化参数确认它的大小.这些大小会在启动时显示报告出来.但是,在分配共享内存segments之前,每个区域的大小会四舍五入到一个内存页面的边界.
这些区域然后分割为子区域,如有必要,以便没有子区域大于一个共享内存segment的相关os限制(unix上针对system v共享内存的shmmax).在这种情况下,可变区域,它会取与os相关的最小子区域大小,因此可变区域
大小会四舍五入为最小子区域的倍数.
         如有可能oracle为整个sga分配一个单一的共享内存segment.但是,如果sga大于一个单一共享内存segment基于os的大小限制,这时oracle会采用一个合适的算法,把这些子区进行分组为多个共享内存segment.


         在oracle7时,sga可变区域必须驻存于连续的内存中.因此,如果os不允许oracle虚拟内存地址在哪个共享内存segment上面附加时,因此会连续附加它们,于是可变segment必须足够小,把它们放入在一个共享内存
segment中.在oracle8不再有这个限制,因为引入了子区域.通常情况下建议提升或加大一个单一共享内存segment的大小,为了允许oracle在可能情况下在单一的共享内存segment中分配sga.我同意这个建议,但仅仅鉴于可管理性,
实例及进程启动这个限制区别或差异可以忽略,否则就是0.







paging
          os为sga和它的页池page pool中为oracle 进程,分配物理内存页.页池包含所有物理系统内存(但不含预留给os本身的).只要一个虚拟内存页面未在物理内存中引用,一个页面就会从页池的自由列表中分配出来.当内存释放掉时页面同时
会返回给自由列表的头部.
          如果自由列表上面的页页数量低于一个可设置的门限(在unix system v系统中为lotsfree),这时os开始查找一些不活跃或不活动的页面进行页出page out.如果在某些特定时间内某些页面没有被引用过,可以认为它们是不知动的.这些不活动的
页面会移到自由列表的尾部,但如果它们被修改过,它们的内容必须首先保存到磁盘.只要自由页面的个数又返回到门限之上,paging就会停止.


          如果自由列表页面数目继续下降,然后os加快paging节奏,以更快速度对一些相关页面进行不活跃化处理.但是,在一些极端内存压力情况下,有可能大量物理内存处于非常活跃状态,这样os查找不活跃页面就会徒劳无功.这种情况下,一些低优先级的进程会
被选中且完全被休眠,为了找到不活跃的页面.虽然os paging行为许多方面是可以调节的,但这种调节作用不大或不明显.

          大量paging活动会对系统性能造成极大的影响.但是,大量使用或占用内存附加有断断续续的paging并不用过分关注.大多系统有足够的不活跃内存可以被页出,它们对于系统性能影响很小或者没有.但是,如果发现一直有light paging,这就要引起注意了,因为
sga中一些适度的活动页面将会重复被页出.大多os具备这种机制,保证oracle把sga锁定在物理内存中,防止它发生paging.如果一直发现paging就要设置lock_sga为true.

          那么如何确定os是否发生paging,如果发生paging了,paging是一直在发生呢或者严重吗?如果你有足够的空闲内存,系统不会存在paging.如果自由内存不足,可以查看每秒页出的页面数.这个度量值可以在winnt下查看性能监控器,或在unix中查阅vmstat.
如果这个值为非0,系统一直处于paging,sga如有可能应被固定到物理内存.这尤其适用于一个paged file system buffer cache的os,如:nt 和solaris.


          但是也要注意,页出比率并不代表os(带有一个paged buffer cache)paging 活动的强度.因为buffered file system writes是由paging subsystem来处理,因而这样就会增大或夸大页出比率.扫描比率可以很好说明或表明这种系统的paging 活动强度.扫描比率
当查找不活跃页面时,每秒查询的页面数量.scan rate通过vmstat的sr列显示出来.如果低于10pages/s就认为paging是light轻微的.





the shared pool
          这部分sga呢经常定义过大.好多dba基本不知道它用于什么,如何确定它是否大小合理.因此他们说只要够大就越好!有时它并不是足够大,但经常这样会造成浪费反而影响了性能.



chunks 大块
           为了更好理解共享池,你至少知道或了解x$ksmsp.它的每条记录代表一大块a chunk of共享池内存

select ksmchcom,ksmchcls,ksmchsiz from x$ksmsp;

kgl handles           recr            496
pl/sql mpcode         recr           1924
sql area              recr           1208

       当每一个共享池大块被分配时,代码把注解传递给实行这个分配的函数.这个注解就是对应上面的ksmchcom,用于描述所分配内存的用途.

       每个大块chunk就是少量大于它包含对象的一个内存块(a little larger than the object it contains),因为它是一个16 byte头(用于识别类型,级别,大块大小,包含用于共享池管理的链式列表
或链表的指针).

       这里列出内存大块的四种主要类型.这些信息可以从x$ksmsp的ksmchcls看到




             free
                 这个自由或空闲的大块不包含一个有效的对象,可以没有限制进行分配

             recr
                 重建大块包含一些对象,这些对象如有必要可以暂时从内存中移走,如有必要可再次重建。比如,与共享sql语句相关的一些大块就是可重建的.
            
             freeabl
                  freeable大块包含一些对象,这些对象正常情况是一个会话或调用所必需的,从此以后可以freed.但是有时侯可以早期或更早就freed,可以是全部
                  或部分.freeable 大块不能从内存暂时被移除,因为它们不能重建.

             perm
                 permanent 内存大块包含一些persist持续的对象.大型或较大的固定内存大块可能包含内部空闲空间,它们会根据需要released into共享池中.


        



free lists
    共享池的自由或空闲大块free chunks根据它们的大小,系统性分为自由列表free lists或者桶buckets.
下面为buckets编号和空闲大块大小


free list buckets and chunks

buckets number                                  free chunk sizes
0                                               up to 79 bytes

1                                               80 bytes to 143 bytes

2                                               144 bytes to 271 bytes

3                                               272 bytes to 527 bytes


4                                               528 bytes to 1039 bytes


5                                               1040 to 2063 bytes

6                                               2064 to 4111 bytes

7                                               4112 to 8207 bytes

8                                               8208 to 16399 bytes

9                                               16400 to 32783 bytes

10                                              32784 之上


   你可能发现每个自由列表的空闲大块大小最左端数值是一个binary power加上16 byte 头.



   当一个进程需要一大块共享池内存时,它首先扫描最适合大小的chunk的目标自由列表.如果最合适的一个大块没有找到,这
时扫描继续到自由列表的尾部去查找,查找下一个最大可用的大块.如果下一个最大可用的大块为>=24 bytes(比需要的),这时
这个大块被分割,余下或剩下的自由或空闲空间大块会添加到合适的自由列表中.但是如果自由列表不包含所需要大小的大块,会从下一个
非空的自由列表中提取或分配take最小的大块.如果所有余下的自由列表是空的empty,然后会尝试一个lru chain scan,这会在后面讲解.

    自由列表扫描,管理,大块分配皆是在shared pool latch保护下进行工作的.显然,如果共享池包含大量的非常小的空闲大块,shared
pool latch会持有相对而言较长的时间(在查找这些特定的自由列表时).这也就是导致对于shared pool latch产生竞争的主要原因.而我们的
dba经常就是简单增大共享池,不幸运的是,这仅仅只会延迟这个shared pool latch竞争的问题,最终会加剧这个问题.





lru lists
       如果一个进程在共享池自由列表上没有找到合适大小的一个空闲内存大块,它会尝试从共享池中移除一些包含重建对象的大块,为了
free一个更大的大块.
       这儿有两类重建大块,一为pinned,二为不pinned.共享池中pinned的大块概念或含义经常与dbms_shared_pool.keep混淆.keeping仅仅
用于library cache objects,这是一个dba的工作.但是当一些包含对象的大块chunk正在使用时,所有的大块会自动pinned.当这些大块pinned时,
是不能freed.但是正常情况下unpinned 重建大块可以freed.
       unpinned recreatable chunks在共享池中是以两个列表方面进行组织的,一个是以lru次序来组织的(least recently used:最近最少使用).
这些就是transient短暂或瞬间的和周期重复性的recurrent lru lists.transient短暂的对象不可能再次需要,然后周期重复性的可能再次需要哟.
这些列表lists的组合或组成或构成composition改变非常快.只要它们unpinned,大块会添加到mru(most recently used) ends末端,反之当它们再次
pinned时,会从列表中(mru)中移除掉.

       当一个进程为了一个新的分配,需要free共享池内存时,大块也会从列表的lru末端移除.大块可以在8个chunks上交替flushed--首先从瞬间列表,然后
从周期重复性列表.大块可以不理会它们的大小而在lru order中进行flush.但是一些大块不能flush.比如,包含一些library cache object的大块,而且
这些object是通过dbms_shared_pool.keep作为标志设置,是不能flush.相反这些大块是从正被pinned的lru lists中移除的.

       unpinned recreatable chunks中的瞬间和周期重复性的lru lists长度,可以查看x$kghlu,连同可以被flushed的大块数目,以及由于pinning和unpinning
从lru lists中添加和移除的大块数量.x$kghlu也显示lru lists完全且不成功flushed的次数,以及最近如此请求失败的大小(the size of the most recent such request
failure).

       lru lists和flushing rate的长度与应用的内存需要有很大关系,以及负荷的变化.较长或者较短的lru lists不一定有问题,发现大量flushing of dead chunks死的
大块这是内存健康管理一部分.但是根据我的经验,如果瞬间列表是周期重复性列表的3倍,很可能共享池定义过大,如果chunk flushes与其它lru操作的比率大于1/20,说明
共享池太小了.






spare free memory备用的空闲内存
       如果直接从自由列表或通过flushing从lru lists中请求一个巨大的内存失败时,oracle仍然还有一个重要的方法.
   
       令人惊奇的是,最后这个方法不是合并连续的空闲大块.当一些大块freed时,可能与下面的大块乾地合并.但是,oracle
只会在显式运行了alter system flush shared_pool才会完全合并共享池空闲空间.因此即使共享池包含了足够连续的空闲空间时,
内存请求可能会失败.如果这个空闲内存变成fragmented不完整或碎片了,成为多个小型的大块,这样不能满足巨大内存分配请求了.


       oracle为了满足巨大内存分配请求的最后一个方法,就是release更多内存到共享池中.oracle会在实例启动时keeps aside一半
的共享池内存.这个内存会慢慢根据内存压力变化进行released.oracle这样作为了减少或限制碎片.

       oracle备用空闲内存,在共享池的主要固定内存大块中是看不见的concealed,以及一些固定表和其它一些真实固定的内存结构.
这种内存不位于或不在共享池的自由列表上,因而不用于立即immediate分配.但是,其信息是包含在v$sgastat中.

       当有必要备用空闲内存的大块会release到共享池中.ora-04031错误:不能在共享池中分配x bytes。这个错误会于所有备用的空闲
内存用完,才会触发这个错误.
       如果运行峰值负荷一些时间了,仍有相当数量的备用空闲内存,这可能表明共享池配置过于大(大于必要).

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9240380/viewspace-662362/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
提供针对oracle初学者及进阶的数据库培训,欢迎大家咨询: 微信: wisdomone 微信公众号: lovedb 工作经历: 中国普天 北京科蓝 北京云和恩墨 北京神州新桥

注册时间:2008-04-04

  • 博文量
    2189
  • 访问量
    12690172