首页 > 代码库 > oracle内存结构
oracle内存结构
一、内存结构
SGA(System Global Area):由所有服务进程和后台进程共享;
PGA(Program Global Area):由每个服务进程、后台进程专有;每个进程都有一个PGA。
二、SGA
包含实例的数据和控制信息,包含如下内存结构:
1)Database buffer cache:缓存了从磁盘上检索的数据块。
2)Redo log buffer:缓存了写到磁盘之前的重做信息。
3)Shared pool:缓存了各用户间可共享的各种结构。
4)Large pool:一个可选的区域,用来缓存大的I/O请求,以支持并行查询、共享服务器模式以及某些备份操作。
5)Java pool:保存java虚拟机中特定会话的数据与java代码。
6)Streams pool:由Oracle streams使用。
7)Keep buffer cache:保存buffer cache中存储的数据,使其尽时间可能长。
8)Recycle buffer cache:保存buffer cache中即将过期的数据。
9)nK block size buffer:为与数据库默认数据块大小不同的数据块提供缓存。用来支持表空间传输。
database buffer cache, shared pool, large pool, streams pool与Java pool根据当前数据库状态,自动调整;
keep buffer cache,recycle buffer cache,nK block size buffer可以在不关闭实例情况下,动态修改。
三、PGA
每个服务进程私有的内存区域,包含如下结构:
1)Private SQL area:包含绑定信息、运行时的内存结构。每个发出sql语句的会话,都有一个private SQL area(私有SQL区)
2)Session memory:为保存会话中的变量以及其他与会话相关的信息,而分配的内存区。
四、SGA COMPONENT
(一)、Buffer Cache
1、DB_CACHE_SIZE
通过参数DB_CACHE_SIZE可指定DB buffer cache的大小
ALTER SYSTEM SET DB_CACHE_SIZE=20M scope=both;
服务进程从数据文件读数据到buffer cache;DBWn从buffer cache写数据到数据文件。
buffer cache的四种状态:
1)pinned:当前块正在读到cache或正写到磁盘,其他会话等待访问该块。
2)clean:
3)free/unused:buffer内为空,为实例刚启动时的状态。
4)dirty:脏数据,数据块被修改,需要被DBWn刷新到磁盘,才能执行过期处理。
同一个数据库中,支持多种大小的数据块缓存。通过DB_nK_CACHE_SIZE参数指定,如
? DB_2K_CACHE_SIZE
? DB_4K_CACHE_SIZE
? DB_8K_CACHE_SIZE
? DB_16K_CACHE_SIZE
? DB_32K_CACHE_SIZE
标准块缓存区大小由DB_CACHE_SIZE指定。如标准块为nK,则不能通过DB_nK_CACHE_SIZE来指定标准块缓存区的大小,应由DB_CACHE_SIZE指定。
例,标准块为8K,则数据库可以设置的块缓存大小的参数如下:
? DB_CACHE_SIZE (指定标准块(这里为8K)的缓存区)
? DB_2K_CACHE_SIZE (指定块大小为2K的缓存区)
? DB_4K_CACHE_SIZE (指定块大小为4K的缓存区)
? DB_16K_CACHE_SIZE (指定块大小为16K的缓存区)
? DB_32K_CACHE_SIZE (指定块大小为32K的缓存区)
2、多种缓冲池(buffer pool)
1)Keep:通过db_keep_cache_size参数指定。
该buffer内的数据可能被重用,以降低I/O操作。该池的大小要大于指定到该池的段的总和。
读入到keep buffer的块不需要过期操作。
2)Recycle:通过db_recycle_cache_size参数指定。
该池中的数据被重用机会较小,该池大小要小于分配到该池的段的总和。读入该池的块需要经常执行过期处理。
3)Default:相当于一个没有Keep与Recycle池的实例的buffer cache,通过db_cache_size参数指定。
3、为对象明确指定buffer pool
buffer_pool子句,用来为对象指定默认的buffer pool,是storage子句的一部分。
对create与alter table、cluster、index语句有效。
如果现有对象没有明确指定buffer pool,则默认都指定为default buffer pool,大小为DB_CACHE_SIZE参数设置的值。
语法:
a.CREATE INDEX cust_idx ON tt(id) STORAGE (BUFFER_POOL KEEP);
b.ALTER TABLE oe.customers STORAGE (BUFFER_POOL RECYCLE);
c.ALTER INDEX oe.cust_lname_ix STORAGE (BUFFER_POOL KEEP);
(二)、Share Pool
1、SHARE_POOL_SIZE
1)Share Pool可通过SHARE_POOL_SIZE参数指定:
SQL> alter system set shared_pool_size=20M scope=both;
2)Share Pool保存的信息被多个会话共享,类型包括:
a.Library Cache
Library Cache又包含共享SQL区与PL/SQL区:
a).共享SQL区保存了分析与编译过的SQL语句。
b).PL/SQL区保存了分析与编译过的PL/SQL块(过程和函数、包、触发器与匿名PL/SQL块)。
b.Data Dictionary Cache
保存了数据字典对象的定义。
c.UGA(User Global Area)
UGA内包含了共享服务器模式下的会话信息。
共享服务器模式时,如果large pool没有配置,则UGA保存在Share Pool中。
(三)、Large Pool
1)Large Pool大小通过LARGE_POOL_SIZE参数指定:
SQL> alter system set large_pool_size=20m scope=both;
2)作用:
a.为I/O服务进程分配内存
b.为备份与恢复操作分配内存
c.为Oracle共享服务器模式与多个数据库间的联机事务分配内存。
通
过从large pool中为共享服务器模式分配会话内存,可以减少share
pool因频繁为大对象分配和回收内存而产生的碎片。将大的对象从share pool中分离出来,可以提高shared
pool的使用效率,使其可以为新的请求提供服务或者根据需要保留现有的数据。
(四)、Java Pool
1、JAVA_POOL_SIZE
通过JAVA_POOL_SIZE参数指定java pool大小。
保存了jvm中特定会话的java code和数据。
2、在编译数据库中的java代码和使用数据库中的java资源对象时,都会用到share pool。
java的类加载程序对每个加载的类会使用大约8K的空间。
系统跟踪运行过程中,动态加载的java类,也会使用到share pool。
(五)、Redo Log Buffer
1、服务进程从用户空间拷贝每条DML/DDL语句的redo条目到redo log buffer中。
2、redo log buffer是一个可以循环使用的buffer,服务进程拷贝新的redo覆盖掉redo log buffer中已通过LGWR写入磁盘(online redo log)的条目。
3、导致LGWR执行写redo log buffer到online redo log的条件
a.用户执行事务提交commit
b.每3秒钟或redo log buffer内已达到1/3满或包含1MB数据
c.DBWn进程将修改的缓冲区写入磁盘时(如果相应的重做日志数据尚未写入磁盘)
(六)、ASMM(Automatic Shared Memory Management)
1、SGA_TARGET
1)SGA_TARGET默认值为0,即ASMM被禁用。需要手动设置SGA各中各组件的大小。
2)当SGA_TARGET为非0时,则启用ASMM,自动调整以下各组件大小:
DB buffer cache(default pool)
shared pool
large pool
streams pool
java pool
但ASSM中, 以下参数仍需要手动指定:
log buffer
keep、recycle、以及非标准块缓冲区
固定SGA以及其他内部分配。
2、启用ASMM需要将STATISTICS_LEVEL设置成TYPICAL或ALL
3、启用ASMM,自动调整SGA内部组件大小后。若手动指定某一组件值,则该值为该组件的最小值。如
手动设置SGA_TARGET=8G,SHARE_POOL_SIZE=1G,则ASMM在自动调整SGA内部组件大小时,保证share pool不会低于1G。
SQL> SELECT component, current_size/1024/1024 size_mb FROM v$sga_dynamic_components;
4、SGA_MAX_SIZE
SGA_MAX_SIZE指定内存中可以分配给SGA的最大值。
SGA_TARGET是一个动态参数,其最大值为SGA_MAX_SIZE指定的值。
五、PGA
(一)Private SQL Area
1、保存了当前会话的绑定信息以及运行时内存结构。这些信息
2、每个执行sql语句的会话,都有一个private sql area。
3、当多个用户执行相同的sql语句,此sql语句保存在一个称为shared sql area。此share sql area被指定给这些用户的private sql area
4、共享服务器模式:private sql area位于SGA的share pool或large pool中
专用服务器模式:private sql area位于PGA中
(二)Cursor、SQL Areas
(三)Work Area
PGA的一大部分被分配给Work Area,用来执行如下操作:
a.基于操作符的排序,group by、order by、rollup和窗口函数。
参数为sort_area_size
b.hash散列连接,
参数为hash_area_size
c.位图合并,
参数为bitmap_merge_area_size
d.位图创建,
参数为create_bitmap_area_size
e.批量装载操作使用的写缓存
(四)Session memory
保存了会话的变量,如登录信息及其他与会话相关的信息,共享服务器模式下,Session memory是共享的。
(五)自动PGA管理
设置PGA_AGGREGATE_TARGET为非0,则启用PGA自动管理,并忽略所有*_area_size的设置。如sort_area_size,hash_area_size等。
默认为启用PGA的自动管理,Oracle根据SGA的20%来动态调整PGA中专用与Work Area部分的内存大小,最小为10MB。
用于实例中各活动工作区(work area)的PGA总量,为PGA_AGGREGATE_TARGET减去其他组件分配的PGA内存。得到的结果,按照特定需求动态分配给对应的工作区。
1)设置PGA_AGGREGATE_TARGET大小的步骤
a.设置PGA_AGGREGATE_TARGET为SGA的20%,对于DSS系统,此值可能过低。
b.运行典型的负载,通过oracle收集的pga统计信息来调整PGA_AGGREGATE_TARGET的值。
c.根据oracle的pga建议调整PGA_AGGREGATE_TARGET大小。
2)禁用自动pga管理
为向后兼容,设置PGA_AGGREGATE_TARGET为0,即禁用pga的自动管理。可使用关联的*_area_size参数调整对应工作区的最大大小。
bitmap_merge_area_size
create_bitmap_area_size
hash_area_size
sort_area_size
一、PGA与SGA的区别。
而PGA程序缓冲区则主要是为了某个用户进程所服务的。这个内存区不是共享的,只有这个用户的服务进程本身才能够访问它自己的PGA区。做个形象的比 喻,SGA就好像是操作系统上的一个共享文件夹,不同用户可以以此为平台进行数据方面的交流。而PGA就好像是操作系统上的一个私有文件夹,只有这个文件 夹的所有者才能够进行访问,其他用户都不能够访问。虽然程序缓存区不像其他用户的进程开放,但是这个内存区仍然肩负着一些重要的使命,如数据排序、权限控 制等等都离不开这个内存区。
二、 为排序设置合理的排序区大小(SORT AREA)。
当用户需要对某些数据进行排序时,数据库是如何处理的呢?首先,数据库系统会将需要排序的数据保存到PGA程序缓存区中的一个排序区内。然后再在这个 排序区内对这些数据进行排序。如需要排序的数据有2M,那么排序区内必须至少要有2M的空间来容纳这些数据。然后排序过程中又需要有2M的空间来保存排序 后的数据。由于系统从内存中读取数据比从硬盘中读取数据的速度要快几千倍,为此如果这个数据排序与读取的操作都能够在内存中完成,无疑可以在很大程度上提 高数据库排序与访问的性能。如果这个排序的操作都能够在内存中完成,显然这是很理想的。但是如果PGA区中的排序区容量不够,不能够容纳排序后的数据,那 会如何呢?此时,系统会从硬盘中获取一个空间,用来保存这需要排序的数据。此时排序的效率就会降低许多。为此在数据库管理中,如果发现用户的很多操作都需 要用到排序,那么用户会设置比较大的排序区,可以提高用户访问数据的效率。
在Oracle数据库中,这个排序区主要用来存放排序操作产生的临时数据。一般来说,这个排序区的大小占据这PGA程序缓存取的大部分空间,这是影响 PGA区大小的主要因素。在小型应用中,数据库管理员可以直接采用其默认的值。但是在一些大型的应用中,或者需要进行大量记录排序操作的数据库系统中,管 理员可能需要手工调整这个排序区的大小,以提高排序的性能。如果系统管理员需要调整这个排序区大小的话,需要通过初始化参数SORT_AREA_SIZE 来实现。为了提高数据访问与排序的性能,数据库系统利用内存比硬盘要快几千倍的实施,会将准备排序的数据临时存放到这个排序区,并在排序区内完成数据的排 序。管理员需要牢记这个原则,并在适当的情况下调整排序区的大小,以提高数据访问与数据排序的性能。
三、 会话区保存着用户的权限等重要信息(USER SESSON DATA)。
在程序缓存区内还包含着一个会话区。虽然绝大部分情况下,管理员不要维护这个会话区,可以让数据库系统进行维护。但是,管理员还是需要了解一下这个会 话区的作用。因为这个会话区直接关系着数据库系统中数据的安全性。数据库系统不仅是存放数据的一个很好的载体,而且在还提供了一个统一管理数据的平台,可 以根据实际需要,为不同的用户设置不同的访问权限。简单的说,在数据库中可以控制用户可以访问哪些数据。从而提高数据的安全性。
当用户进程与数据库建立会话时,系统会将这个用户的相关权限查询出来,然后保存在这个会话区内。如此的话,用户进程在访问数据时,系统就会核对会话区 内的用户权限信息,看看其是否具有相关的访问权限。由于系统将这个用户的权限信息存放在内存上,所以其核对用户权限的速度非常的快。因为系统不用再去硬盘 中读取数据,直接从内存中读取。而从内存读取数据的效率要比硬盘上快几千倍。
通常情况下,这个会话区内保存了会话所具有的权限、角色、性能统计等信息。这个会话区一般都是由数据库进行自我维护的,系统管理员不用干预。
四、 堆栈区保存变量信息(STACK SPACE)。
有时候为了提高SQL语句的重用性,会在语句中使用绑定变量。简单的说,就是SQL语句可以接受用户传入的变量。从而用户只需要输入不同的变量值,就 可以满足不同的查询需求。如现在用户需要查询所有员工的信息。然后其又要查询所有工龄在3年以上的员工等等。此时其实他们采用的是同一个SQL语句,只是 传递给系统的变量不同而已。这可以在很大程度上降低数据库开发的工作量。这个变量在Oracle数据库系统中就叫做绑定变量。利用绑定变量可以加强与用户 的互动性。另外在这个堆栈区内还保存着会话变量、SQL语句运行时的内存结构等重要的信息。
通常情况下,这个堆栈区跟上面讲到的会话区一样,都可以让数据库系统进行自我维护,而管理员不用参与到其中。这些分区的大小,也是系统根据实际情况来进行自动分配的。当这个用户会话结束时,系统会自动释放这些区所占用的空间。
五、 游标区 (CURSOR STATE)。
无论是SQLServer数据库还是Oracle数据库中,有时候都需要用到游标技术。当运行使用游标的语句时,Oracle数据库系统会在程序缓存 区中间为其分配一块区域。这块区域就叫做游标区。通常情况下,游标用来完成一些比较特殊的功能。而且一般来说,采用游标的语句要比其他语句的执行效率低一 点。为此管理员在使用游标的时候,还是需要慎重。
游标区是一个动态的区域。当用户执行游标语句时,系统就会在这个游标区内创建一个区域。当关闭游标时,这个区域就会被释放。这创建与释放,需要占用一 定的系统资源,花费一定的时间。为此在使用游标时,如果频繁的打开和关闭游标,就会降低语句的执行性能。所以笔者建议,在写语句时,如果真的有必要使用游 标技术时,则要注意游标不要频繁的打开和关闭。
另外在Oracle数据库中,还可以通过限制游标的数量来提高数据库的性能。如在数据库系统中有一个初始化参数OPEN_CURSORS。管理员可以 根据实际的需要,来设置这个参数,控制用户能够同时打开游标的数目。不过需要注意的是,在确实需要才有游标的情况下,如果硬件资源能够支持的话,那么就需 要放宽这个限制。这可以避免用户进程频繁的打开和关闭游标。因为频繁的打开和关闭游标这对游标的操作是不利的,会影响数据库的性能。
从以上的分析中可以看出,程序全局区(PGA)主要包含排序区、会话区、堆栈区和游标区四个部分的内容,他们各司其职,完成用户进程与数据库之间的会 话。通常情况下,系统管理员主要关注的是排序区,在必要时需要手工调整这个排序区的大小。另外需要主要的是,游标区是一个动态的区域,在游标打开时创建, 关闭时释放。故在数据库开发时,不要频繁的打开和关闭游标可以提高游标操作的效率,改善数据库的性能。其他分区的内容管理员只需要了解其用途,日常的维护 交给数据库系统来完成即可。
oracle内存结构