欢迎来到学术参考网

Oracle内存组成分析

发布时间:2015-08-15 10:59

摘 要:要想提高oracle的性能,就不得不认真研究Oracle的内存配置。可以说内存的配置是最影响Oracle性能的重要问题。本文重点阐述Oracle的内存组成。

关键词:oracle;内存结构;内存组成
  Oracle的内存总体说来,可以分为两大部分:共享部分和进程独享部分。而这两部分根据功能不同,还分为不同的内存池和内存区。Oracle的内存组成详细阐述如下:
1系统全局区
  系统全局区(SGA,System Global Area)。是一组包含一个Oracle实例的数据和控制信息的共享内存结构。其中具有两个很重要的特性:
  (1)系统全局区是共享的。多个用户可以同时登录这个实例,并且能够同时访问系统全局区中的信息;(2)一个系统全局区只为一个实例服务。即当一台机器上有多个实例运行时,每个实例都有一个自己的系统全局区,尽管系统全局区来自于操作系统的共享内存区,但实例之间不能相互访问对方系统全局区区的信息。(3)Oracle进程和一个系统全局区就构成了一个Oracle实例。当实例启动时,Oracle会自动从系统中分配内存给系统全局区,而实例关闭时,操作系统会回收这些内存。(4)系统全局区区是可读写的。所有登录到实例的用户都能读取系统全局区中的信息,同时服务进程也会将oracle执行操作后修改的信息写入系统全局区区。
  系统全局区主要包括以下的数据结构:数据缓存、重做日志缓存、共享池、Java池、大池、流池、数据字典缓存。
1.1 数据缓存
  数据缓存专门用于存放从数据文件中读取的的数据块拷贝的区域。如果需要访问的数据块已经在数据缓存中,就直接读写内存中的相应区域,而无需读取数据文件,从而大大提高性能。数据缓存对于所有oracle进程都是共享的,即能被所有oracle进程访问。数据缓存被分为多个集合,这样能够大大降低多CPU系统中的争用问题。
1.2重做日志缓存
  重做日志缓存是系统全局区中一段保存数据库修改信息的缓存。这些信息被存储在重做条目中。重做条目中包含了由于INSERT、UPDATE、DELETE、CREATE、ALTER或DROP所做的修改操作而需要对数据库重新组织或重做的必须信息。在必要时,重做条目还可以用于数据库恢复。参数LOG_BUFFER决定了重做日志缓存的大小。它的默认值是512K,最大可以到4G。当系统中存在很多的大事务或者事务数量非常多时,可能会导致日志文件IO增加,性能降低。这时可以考虑增加LOG_BUFFER值。
1.3 共享池
  系统全局区中的共享池由库缓存、字典缓存、用于并行执行消息的缓冲以及控制结构组成。其大小由参数共享池大小决定。在32位系统中,这个参数的默认值是8M,而64位系统中的默认值位64M。最大为4G。对于共享池的内存管理,是通过修正过的LRU算法表来实现的。
  共享池包括下面几个组成部分:
  (1)库缓存
  库缓存中包括共享SQL区、PL/SQL存储过程和包以及控制结构。任何用户都可以访问共享SQL区。因此库缓存存在于系统全局去的共享池中。
  (2)字典缓存
  数据字典是有关于数据库的参考信息、数据库的结构信息和数据库中的用户信息的一组表和视图的集合。在SQL语句解析的过程中,Oracle可以非常迅速的访问这些数据字典。因为Oracle对数据字典访问比较频繁,此内存中有两处地方被专门用于存放数据字典。数据字典缓存也被称为行缓存,因为它是以记录行为单元存储数据的,而不像数据缓存是以数据块为单元存储数据。内存中另外一个存储数据字典的地方是库缓存。所有Oracle的用户都可以访问这两个地方以获取数据字典信息。
  (3)保留共享池
  为了拥有足够空间缓存大程序块,Oracle专门从共享池内置出一块区域来来分配内存保持这些大块。这个保留共享池的默认大小是共享池的5%。它的大小也可以通过参数SHARED_POOL_RESERVED_SIZE来调整。保留区是从共享池中分配,不是直接从系统全局去中分配的,它是共享池的保留部分,用于存储大块段。
  共享池中内存大于5000字节的大段就会被存放在共享池的保留部分。而这个大小限制是通过隐含参数_SHARED_POOL_RESERVED_MIN_ALLOC来设定的。除了在实例启动过程中,所有小于这个数的内存段永远都不会放到保留部分中,而大于这个值的大内存段也永远不会存放到非保留区中,即使共享池的空间不够用的情况下也是如此。
1.4 Java池
  Java池是系统全局区中的一块可选内存区,属于系统全局区中的可变区。Java池的内存是用于存储所有会话中特定Java代码和JVM中数据。Java池的使用方式依赖于Oracle服务的运行模式。Java池的大小由参数JAVA_POOL_SIZE设置,最大可到1G。在Oracle 10g以后,提供了一个新的Java池建议器,来辅助数据库管理员调整Java池大小。
1.5 大池
  大池是系统全局区中的一块可选内存池,根据需要时配置。通过从大池中分配会话内存给共享服务或并行查询,oracle可以使用共享池主要来缓存共享SQL,以防止由于共享SQL缓存收缩导致的性能消耗。此外,为Oracle备份和恢复操作、IO服务进程和并行查询分配的内存一般都是几百K,这么大的内存段从大池比从共享池更容易分配得到。
  参数LARGE_POOL_SIZE设置大池的大小。大池是属于系统全局区的可变区的,它不属于共享池。对于大池的访问,是受到large memory latch保护的。它没有可重建内存段,因此也不用LRU链表来管理。大池最大大小为4G。为了防止大池中产生碎片,隐含参数_LARGE_POOL_MIN_ALLOC设置了大池中内存段的最小大小,默认值是16K。
1.6流池
  流池是Oracle 10g中新增加的。是为了增加对流的支持。流池也是可选内存区,属于系统全局区中的可变区。它的大小可以通过参数STREAMS_POOL_SIZE来指定。如果没有被指定,oracle会在第一次使用流时自动创建。如果设置了SGA_TARGET参数,Oracle会从系统全局区中分配内存给流池;如果没有指定SGA_TARGET,则从数据缓存中转换一部分内存过来给流池。转换的大小是共享池大小的10%。Oracle同样为流池提供了一个流池建议器。
2 程序全局区
  程序全局区(PGA,Program Global Area),是一块包含一个服务进程的数据和控制信息的内存区域。它是Oracle在一个服务进程启动时创建的,是非共享的。一个Oracle进程拥有一个程序全局区内存区。一个程序全局区也只能被拥有它的那个服务进程所访问,只有这个进程中的Oracle代码才能读写它。
  程序全局区由两 组区域组成:固定程序全局区和可变程序全局区。固定程序全局区的大小是固定的,包含了大量原子变量、小的数据结构和指向可变程序全局区的指针。可变程序全局区是一个内存堆。程序全局区堆包含用于存放X$表的的内存。总的来说,程序全局区的可变区中主要分为以下三部分内容:
1) 私有SQL区
2) 游标和SQL区
3) 会话内存
  (1)私有SQL区
  私有SQL区包含了绑定变量值和运行时期内存结构信息等数据。每一个运行SQL语句的会话都有一个块私有SQL区。所有提交了相同SQL语句的用户都有各自的私有SQL区,并且他们共享一个共享SQL区。因此,一个共享SQL区可能和多个私有共享区相关联。
  (2)游标和SQL区
  一个Oracle预编译程序或OCI程序的应用开发人员能够很明确的打开一个游标,或者控制一块特定的私有SQL区,将他们作为程序运行的命名资源。另外,oracle隐含的为一些SQL语句产生的递归调用也使用共享SQL区。私有SQL区是由用户进程管理的。如何分配和释放私有SQL区极大的依赖与你所使用的应用工具。而用户进程可以分配的私有SQL区的数量是由参数OPEN_CURSORS控制的,它的默认值是50。
  (3)会话内存
  会话内存是一段用于保存会话变量和其他预会话相关信息的内存。对于共享服务器模式下,会话内存是共享的。对于复杂的查询,运行区的很大一部分被那些内存需求很大的操作分配给SQL工作区。工作区的大小是可以调整的。一般来说,大的工作区能让一些特定的操作性能更佳,但也会消耗更多的内存。工作区的大小足够适应输入的数据和相关的SQL操作所需的辅助的内存就是最优的。如果不满足,因为需要将一部分数据放到临时表空间磁盘上处理,操作的响应时间会增长。
3用户全局区
  程序全局区是一段包含一个Oracle服务或后台进程的数据和控制信息的内存。程序全局区的大小依赖与系统的配置。在专用服务模式下,一个服务进程与一个用户进程相关,程序全局区就包括了堆空间和用户全局区 (UGA,The User Global Area)。而用户全局区由用户会话数据、游标状态和索引区组成。在共享服务模式下,一个共享服务进程被多个用户进程共享,此时用户全局区是共享池或大池的一部分。
  程序全局区和用户全局区之间的区别可以理解为进程和会话之间的区别。在专用服务模式下,进程和会话是一对一的;而在共享服务模式下,进程和会话是一对多的关系。程序全局区是服务于进程的,它包含的是进程的信息;而用户全局区是服务于会话的,它包含的是会话的信息。因此,在共享服务模式下,程序全局区和用户全局区之间的关系也是一对多的。
4 调用全局区
  与其他的全局区不同,调用全局区 (CGA,The Call Global Area)的存在是瞬间的。它只存在于一个调用过程中。对于实例的一些低层次的调用需要调用全局区,包括: 解析一条SQL语句;执行一条SQL语句;取一条SELECT语句的输出值。
  如果语句产生了递归调用,则需要为每个递归调用分配一个调用全局区。如上所述,递归调用是在语句解析、优化器产生语句查询计划、DML操作时需要查询或修改数据字典信息的调用。因为无论那种模式,会话在做调用时总需要一个进行进行处理。特别是在共享服务模式下时,如果发现一次调用很久没有响应,则可能需要增加程序全局区的大小。
5 软件代码区
  软件代码区(SCA,Software Code Area)是一部分用于存放那些正在运行和可以被运行的代码的内存区。Oracle代码一般存储在一个不同于用户程序存储区的软件代码区,而用户程序存储区是排他的、受保护的区域。软件区的大小一般是固定的,只有Oracle软件升级或重装后才会改变。在不同操作系统下,这部分区域所要求的大小也不同。软件区是只读的,可以被安装成共享的或非共享的。
结束语:内存的配置是影响Oracle性能的重要问题,值得引起大家的重视与关注,而且还需要在实践中不断地探索与实践,使之达到最优。

上一篇:论软件开发中的项目管理

下一篇:谈电子EDA技术的应用与发展