当oracle数据库实例启动的时候,oracle数据库会分配一个内存区并且会启动后台进程。
内存区存储的信息如下:
・程序代码
・每个连接会话的信息,包括当前没激活的会话
・在进程间共享和通信的锁数据信息
・缓存数据,比如数据块和重作记录,它们也会存在于磁盘
基础的内存结构
oracle数据库包含几个内存区域,每个内存区域都包含好几个子组件
System global area (SGA) 系统全局区
SGA是一组共享内存结构,称为SGA组件,包含一个oracle数据库实例的数据和控制文件信息。所有的服务器进程和后台进程共享SGA内存区,SGA中存储的数据包括缓存的数据块和sql共享区域。
Program global area (PGA) 程序全局区
PGA是一个非共享内存区域,它只包含用于Oracle进程使用的数据和控制信息。当Oracle进程启动时,Oracle数据库创建PGA。
每个服务器进程和后台进程都有它自己的PGA内存区,单个PGA的集合是总的实例PGA的大小,在系统初始化参数中设置的是实例PGA的大小。
User global area (UGA) 用户全局区
UGA是与用户会话相关联的内存。
Software code areas
软件代码区是用来存储正在运行或可以运行代码的区域。Oracle数据库代码存储在一个软件领域,通常在不同的位置,从用户程序――更高级的或受保护的位置。
下图显示了这些内存之间的关系:
oracle 数据库内存管理
内存管理包括为oracle数据库实例内存结构分配最佳大小,以满足数据库更改的需求。oracle数据库内存管理基于初始化相关内存参数的设置
内存管理的基本模式如下:
・内存自动化管理
先给数据库实例分配一个目标内存大小,实例会自动调整到目标内存大小并根据需要在SGA和PGA之间重新分配内存。
・自动共享内存管理
这种管理模式实现部分自动化,为SGA设置了一个目标大小,然后可以选择为PGA设置聚合目标大小,或者单独管理PGA工作区域。
・内存管理手册
与设置总内存大小不同,可以设置许多初始化参数,以单独管理SGA和实例PGA组件。
如果你通过DCBA(Database Configuration Assistant)创建oracle数据库并选择默认的初始化设置,此时自动化管理模式就是默认的内存管理模式。
UGA(User Global Area)概述
UGA是会话内存,它是分配给会话变量的内存,它主要存储登录信息、以及数据库会话所需的其它信息,实际上UGA存储的是会话的状态。
下图是UGA的结构:
如果会话将PL / sql包加载到内存中,那么UGA将包含包状态,即在特定时间存储在所有包变量中的值集。
当包的子程序更改变量时包的状态也会发生更改,默认情况下包变量是唯一的,并且会持久保存。
OLAP页面池也存储在UGA中。这个池管理OLAP数据页面,它相当于数据块。页面池是在OLAP会话开始时分配的,并在会话结束时释放。当用户查询多维对象(如多维数据集)时,OLAP会话将自动打开。
UGA对于数据库会话必须是可用的。由于这个原因,在使用共享服务器连接时,UGA不能存储在PGA中,因为PGA是特定于单个进程的。因此,UGA在使用共享服务器连接时存储在SGA中,使任何共享服务器进程都可以访问它。当使用专用的服务器连接时,UGA存储在PGA中。
PGA(Program Global Area)概述
PGA是oracle服务器进程所独有的内存区,而不是系统上其它进程或线程所共享的内存区。因为PGA是特定于进程的,所以它从来不是在SGA中分配的。
PGA是一个内存堆,它包含专用和共享服务器进程所需要的session变量。服务器进程分配它在PGA中需要的内存结构。
下图显示了一个没有为共享服务器配置的实例PGA(所有PGA的集合)。可以使用初始化参数设置PGA的最大值,个人PGA可以根据需要增加到这个目标大小。
PGA详细内容
PGA被细分为不同的区域,每个区域都有不同的作用。
下图为专用服务器会话所需的PGA内存结构:
一个Private sql Area包含关于解析的sql语句和其他特定会话特定信息的信息。
当服务器进程执行sql或PL / sql代码时,进程将会使用私有sql区域存储绑定变量值(绑定变量详解http://blog.csdn.net/tianlesoftware/article/details/5458896)、查询执行状态信息和查询执行工作区域。
不要混淆在PGA中的私有sql区域和共享的sql区域,共享sql区域在SGA中存储执行计划。在相同或不同的会话中,多个私有sql区域可以指向SGA中的一个执行计划。例如,在一个会话中执行“SELECT * FROM sales”的20次执行和在不同会话中执行相同查询的10次执行可以共享相同的计划。每个执行的私有sql区域不共享,可能包含不同的值和数据。
游标是特定私有sql区的名称。如下图所示,你可以将游标看作是客户端上的指针和服务器端的状态。因为游标与私有sql区域密切相关,所以术语有时可以相互互换使用。
一个私有sql区可以划分为如下几个区域:
・The run-time area(运行时区)
这个区域包含查询执行状态信息。例如The run-time area可以跟踪到目前为止在全表扫描中检索到的行数信息。当游标执行结束时The run-time area被释放。
oracle创建The run-time area作为执行请求的第一步。对于DML语句,当sql语句关闭时,The run-time area将会被释放。
・The persistent area(持续数据区)
这个区域包含绑定变量值。当语句执行时会提供一个绑定变量值到sql语句。只有当游标关闭时 The persistent area 才会被释放。
客户端进程负责管理私有sql区。尽管客户端进程可以分配的私有sql区的数量受到初始化参数“OPEN_CURSORS”
的限制,但是私有sql区的分配很大程度上还是取决于应用程序。
尽管大多数用户依赖于数据库实用程序的自动游标处理,但Oracle数据库编程接口提供给了开发人员更多的控制游标。一般来说,应用程序应该关闭所有不再被使用的开放游标,以释放持续数据区,并最小化用户所需的内存。
工作区是用于内存密集型操作的PGA内存的私有区域。
例如,sort运算符利用sort区域来将一行数据进行排序。类似的,一个散列连接操作符使用一个散列区域从它的左输入构建一个哈希表,而位图合并使用位图合并区域来合并从多个位图索引扫描中检索到的数据。
查询.png" alt="dd6890603563c74120e9dc4bcd1ba0e9.png" src="https://s4.51cto.com/oss/201710/20/dd6890603563c74120e9dc4bcd1ba0e9.png">
在前面的示例中,运行时区跟踪全表扫描的进度。会话在散列区执行散列连接以匹配两个表中的行。排序则在排序区中进行。
如果处理的数据量大于工作区的容量,那么oracle数据库会将输入的数据分成小块。这样的话数据库就先会处理内存中的数据片段,然后将其余的数据写入临时磁盘以便稍后处理。
当启动自动PGA内存管理时,数据库会自动调整sql工作区的大小,当然,也可以手动调整sql工作区的大小。
一般来说,较大的sql工作区是以高内存消耗换取优秀的操作性能。最理想的sql工作区的大小是足以容纳由其关联的sql操作符分配的输入数据和辅助内存结构。否则响应时间会增加,因为必须要将部分输入数据缓存在磁盘上。在极端情况下,如果sql工作区的容量远远小于输入数据大小,那么数据库必须对数据块执行多次传递,从而极大地增加响应时间。
专用服务器和共享服务器模式下的PGA的使用
PGA内存区的分配取决于数据库采用的是专用服务器连接还是共享服务器连接。