Oracle内存结构与管理
内存结构
SGA(System Global Area):系统全局区。
PGA(Processor Global Area):进程全局区。
UGA(User 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 没有明显地设置,则它默认为10MB 或SGA 容量的20% :
WORKAREA_SIZE_POLICY :MANUAL 或 AUTO (默认值)
如果为MANUAL 则会使用排序区和散列区大小参数来分配内存量。
PGA_AGGREGATE_TARGET :控制所有工作区(即排序区和散列区)总共应分配内存量。可以在系统级或会话级打开自动PGA 内存管理。
与PGA 相关的视图有:v$pgastat ,v$pag_target_advice (顾问视图)。
注意的几点:
1. PGA_AGGREGATE_TARGET 只是一个理论上的上限“目标”,并不会在启动时真正分配这么多内存。而且在有必要时会超过这个值。
2. 串行会话只使用目标值中很少的一部分,每个工作区只会使用大约5% 或更少。并行查询最多可以使用PGA_AGGREGATE_TARGET 的30% ,即每个并行进程使用的内存量大约为:0.3* PGA_AGGREGATE_TARGET/ 并行进程数。
3. 尽管工作区在PGA 内存中所占的比重很大,但PGA 内存中并非只有工作区。PGA 内存分配涉及很多方面,其中只有工作区在数据库实例的控制之下。如果创建并执行一个PL/SQL 代码块将数据填入一个很大的数组,如果采用专用服务器模式,则UGA 在PGA 中,倘若是这样,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 :共有8 个CACHE_SIZE 参数,控制各可用缓冲区缓存的大小。主要用于支持可传输的表空间而非性能调优。
l LOG_BUFFER
l SGA_TARGET :10G 及以上版本用于自动SGA 内存管理。
l SGA_MAX_SIZE :用于控制DB 启动并运行中SGA 可以达到的最大大小。
说明:9i 需手动设置各值大小,10G 才开始有自动SGA 内存管理,自动管理时只需把SGA_TARGET 参数设置为所需的SGA 大小即可,各池的值由系统自动设置。
各池的内存以一种称为颗粒(granule, 也称区组)的单位来分配,其大小为4MB 、8MB 或16MB 的内存区。
可以通过视图v$sgastat 查看各池大小及分配情况:select * from v$sgastat ;
可以通过视图v$sga_dynamic_components 查看各池所用的颗粒大小。
select component, granule_size from v$sga_dynamic_components;
l 固定SGA (fixed 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 9i 中SELECT 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 类的共享部分,由每个会话使用。每个会话的状态存储在PGA 的UGA 中,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% 的空间。
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com