Oracle内存结构与管理(1)

Oracle内存结构与管理

 

内存结构

SGA(System Global Area):系统全局区。

PGA(Processor Global Area):进程全局区。

UGAUser Global Area:与特定会话相关联,如果使用共享服务器模式则它在SGA中分配,因为每个共享服务器进程都能访问它,如果使用专用服务器模式,则它在PGA中分配。

 

9i开始,有两种方法管理PGA中的非UGA内存:手动/自动PGA内存管理。

9i中,如果采用共享服务器模式,则只能使用手动PGA管理。

 

手动PGA内存管理:

SORT_AREA_SIZE:排序使用的内存。

SORT_AREA_RETAINED_SIZE:排序完成后用于保存已排序数据内存总量,排好序放不下的数据将写到临时表空间中。

HASH_AREA_SIZE:存储散列表所用的内存量。

 

注意的几点:

1.         *_AREA_SIZE参数控制的是操作所用的最大内存量,只是对一个操作的限制而非会话。一个会话中一个查询可能有多个操作,所以可能超过实际的设置值。这些内存根据需要而分配,而且可以收缩。

2.         SORT_AREA_SIZE ~ SORT_AREA_RETAINED_SIZE 这部分内存分在PGA中分配,SORT_AREA_RETAINED_SIZE 这部分内存分在UGA中分配。

 

自动PGA内存管理(APMM):

10G默认处于启用状态,两个初始化参数需要指定,如果PGA_AGGREGATE_TARGET没有明显地设置,则它默认为10MBSGA容量的20%

WORKAREA_SIZE_POLICYMANUAL AUTO(默认值)

如果为MANUAL则会使用排序区和散列区大小参数来分配内存量。

PGA_AGGREGATE_TARGET:控制所有工作区(即排序区和散列区)总共应分配内存量。可以在系统级或会话级打开自动PGA内存管理。

PGA相关的视图有:v$pgastatv$pag_target_advice(顾问视图)。

注意的几点:

1.         PGA_AGGREGATE_TARGET只是一个理论上的上限“目标”,并不会在启动时真正分配这么多内存。而且在有必要时会超过这个值。

2.         串行会话只使用目标值中很少的一部分,每个工作区只会使用大约5%或更少。并行查询最多可以使用PGA_AGGREGATE_TARGET30%,即每个并行进程使用的内存量大约为:0.3* PGA_AGGREGATE_TARGET/并行进程数。

3.         尽管工作区在PGA内存中所占的比重很大,但PGA内存中并非只有工作区。PGA内存分配涉及很多方面,其中只有工作区在数据库实例的控制之下。如果创建并执行一个PL/SQL代码块将数据填入一个很大的数组,如果采用专用服务器模式,则UGAPGA中,倘若是这样,Oracle只能任由你这样做,而无法干涉。数据库本身无法控制PGA中分配的这些内存。不过,数据库很清楚我们做了什么。尽管有些内存无法控制,但它不会忽略这部分内存;而是会识别已经使用的内存,并相应地减少为工作区分配的内存大小。由于一些PGA内存不在Oracle的控制之下,所以如果在PL/SQL代码中分配了大量很大的数据结构,就很容易超出PGA_AGGREGATE_TARGET。这说明PGA_AGGREGATE_TARGET不能算是一个硬性限制,而更应该算是一个请求。

 

SGA内存管理:

SGA中的内存池:

l         Java pool: 为数据库中运行的JVM分配的固定内存。

l         Large pool: 共享服务器连接使用它作为会话内存,并行执行特性使用它作为消息缓冲区,另外RMAN使用它作为磁盘I/O缓冲区。

l         Shared pool: 包含共享游标、存储过程、状态对象、字典缓存等。

l         Stream pool: Oracle流是数据库的一个数据共享工具。

l         “Null pool”: 这个池其实没有名字。这是块缓冲区(缓存的数据库块)、重做日志缓冲区和“固定SGA“区专用的内存。

SGA影响最大的参数:

l         JAVA_POOL_SIZE

l         SHARED_POOL_SIZE

l         LARGE_POOL_SIZE

l         DB_*_CACHE_SIZE:共有8CACHE_SIZE参数,控制各可用缓冲区缓存的大小。主要用于支持可传输的表空间而非性能调优。

l         LOG_BUFFER

l         SGA_TARGET10G及以上版本用于自动SGA内存管理。

l         SGA_MAX_SIZE:用于控制DB启动并运行中SGA可以达到的最大大小。

说明:9i需手动设置各值大小,10G才开始有自动SGA内存管理,自动管理时只需把SGA_TARGET参数设置为所需的SGA大小即可,各池的值由系统自动设置。

 

各池的内存以一种称为颗粒(granule, 也称区组)的单位来分配,其大小为4MB8MB16MB的内存区。

可以通过视图v$sgastat查看各池大小及分配情况:select * from v$sgastat ;

可以通过视图v$sga_dynamic_components查看各池所用的颗粒大小。

select component, granule_size from v$sga_dynamic_components;

 

l         固定SGAfixed SGA):

它是SGA中的一个组件,它有一组指向SGA中其他组件的变量及参数值,它一般都很小,可以把它想成是SGA中的“自启”区,通过它才能找到SGA中的其他区。

l         重做缓冲区(redo buffer)

缓存重做日志,取值为MAX(512KB,128*CPU个数)LGWR会在以下某个情况发生时启动对这个区的刷新输出:

Ø         3秒一次

Ø         无论何时有人提交请求

Ø         要求LGWR切换日志文件

Ø         重做缓冲区1/3满,或者包含了1MB的缓存重做日志数据

注意在引入增量检查点后,日志切换操作不一定触发检查点进程。

 

l         块缓冲区缓存(block buffer cache:

SGA中一个很重要的区,各个段的已缓存块可放在3个位置上:

默认池(default pool):所有段块一般都在这个池中缓存。

保持池(keep pool):缓存访问相当频繁的段。

回收池(recycle pool):缓存访问很随机的大段,一般不会多次访问,需快速回收。

利用一定的算法及两个列表管理缓存块:

脏块列表(写列表):其中的块需要由DB块写入器(DBWn)写入磁盘。

非脏块列表(LRU列表,Least Recently Used):也跟踪缓存区中未使用的内存块。

可通过DB Buffer Cache 顾问设置DB Buffer Cache,视图:v$db_cache_advice

Select name, size_for_estimate, size_factor, estd_physical_reads from v$db_cache_advice;

每条记录都预先估计了在DB高速缓存区大小固定的情况下所需的物理读取数。

 

l         共享池

包含共享游标、存储过程、状态对象、字典缓存等。特别是数据字典,访问非常频繁,须缓存在池中。共享池的特点是有大量小的内存块(chunk),一般为4 KB或更小,目标是使用小块的内存来避免碎片问题。共享池中的内存根据LRU(最近最少使用)的原则来管理。如果你不用某个对象,它就会丢掉。为此提供了一个包,名叫DBMS_SHARED_POOL,这个包可用于改变这种行为,强制性地“钉住”共享池中的对象。可以使用这个过程在数据库启动时加载频繁使用的过程和包,并使它们不至于老化。如果你真的想破坏Oracle的共享池,最容易的办法是不使用绑定变量。

Oracle 9iSELECT SUM(BYTES) FROM V$SGASTAT总是略大于SHOW PARAMETER SHARED_ POOL_SIZE。这是因为共享池还保存了另外的许多结构,它们不在相应参数的作用域内。SHARED_POOL_SIZE通常占了共享池(SUM(BYTES)报告的结果)中最大的一部分,但这不是共享池中惟一的一部分。V$SGASTAT中的“共享池”与参数SHARED_POOL_SIZE的命名让人很容易混淆,这个参数对共享池大小贡献最大,但是它并不是惟一有贡献的参数。不过,在Oracle 10g 及以上版本中,假设你使用手动的SGA内存管理,二者之间存在一对一的对应关系。

可以利用共享池顾问程序帮助设置大小,查询视图:v$shared_pool_advice

Select shared_pool_size_for_estimate, shared_pool_size_factor, estd_lc_time_saved

From v$shared_pool_advice

这个查询说明了共享池大小确定的情况下所节省的库高速缓存分析时间量,而且通过20条记录返回了共享池从当前一半大小到两倍大小时的估计时间。

 

l         大池(large pool

它用于大块内存的分配,大块内存分配则是得到一块内存后加以使用,然后就到此为止,没有必要缓存这个内存。大池就是一个回收型的内存空间,共享池则更像是保持缓冲区池。

大池专门用于以下情况:

Ø         共享服务器连接,用于在SGA中分配UGA区。

Ø         语句的并行执行,允许分配进程间的消息缓冲区,这些缓冲区用于协调并行查询服务器。

Ø         备份,在某些情况下用于RMAN磁盘I/O 缓冲区。

使用共享服务器连接时,并不是一定得使用大池。如果没有大池,而且使用了一个共享服务器连接,就会像Oracle 7.3及以前版本中一样从共享池分配空间。过一段时间后,这会导致性能恶化,一定要避免这种情况。如果DBWR_IO_SLAVES或者PARALLEL_MAX_SERVERS参数设置为某个正值,大池会默认为某个大小。如果使用了一个用到大池的特性,建议手动设置大池的大小。

 

l         Java

支持在数据库中运行Java。如果采用专用服务器模式,Java池包括每个Java类的共享部分,由每个会话使用。每个会话的状态存储在PGAUGA中,9i及以前版本中Java池的总大小是固定的,需要估计应用的总需求,再把估计的需求量乘以所需支持的并发会话数,所得到的结果能指示出Java池的总大小。每个Java UGA会根据需要扩大或收缩,但是要记住,池的大小必须合适,所有UGA加在一起必须能同时放在里面。在 Oracle10g 及以上版本中,这个参数可以修改,Java池可以随着时间的推移而扩大和收缩,而无需重启数据库。

使用共享服务器连接来连接Oracle时,Java池包括以下部分:

Ø         每个Java类的共享部分。

Ø         UGA中用于各会话状态的部分,这是从SGA中的JAVA_POOL分配的。UGA中余下的部分会正常地在共享池中分配,或者如果配置了大池,就会在大池中分配。

 

l         流池(stream pool

流池是一个新的SGA结构,从Oracle 10g开始才增加的。流(Stream)本身就是一个新的数据库特性,Oracle9i Release 2及以上版本中才有。它设计为一个数据库共享/复制工具,这是Oracle在数据复制方面发展的方向。流池(或者如果没有配置流池,则是共享池中至多10%的空间)会用于缓存流进程在数据库间移动/复制数据时使用的队列消息。

流池只对使用了流数据库特性的系统是重要的。在这些环境中,必须设置流池,以避免因为这个特性从共享池“窃取”10%的空间。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值