Oracle 内存结构

Oracle内存存储了数据字典信息、缓冲的应用数据、sql语言、PL\SQL和java程序数据,以及事务、控制、用户请求信息。

1)系统全局区SGA

SGA是数据库所有用户共享的存储区,它在实例启动时分配,实例关闭时回收。在动态调整SGA个缓冲大小时,要注意的是必须低于初始化参数表SGA_MAX_SIZE的值。Oracle 10g以后SGA自动内存管理,只需要配置初始化参数SGA_TARGET。SGA中还有一部分内存区必须手动调整,这些区有keep/recycle缓冲区,相应的初始化参数是DB_KEEP_CACHE_SIZE和DB_RECYCLE_CACHE_SIZE.还有非标准数据块参数,DB_nK_CACAHE_SIZE,n=

2)数据库缓冲区

数据库缓存区是SGA中的一个高速缓冲区域,用来存储最近从数据文件中读出来的数据块,如表、索引数据块。数据库缓存区是Oracle提高访问速度的一种有效方法。SGA是所有用户共享的。处理查询时,服务器进程会先从数据库缓存区查找所需数据块,只有缓冲区中没有时才会访问磁盘。

数据库缓冲区对数据库的性能有很大影响。在Oracle 10g之前,数据库缓存区的大小是由DB_BLOCK_BUFFERS参数决定。这个参数可在数据库服务器中的初始化参数文件中设置。数据库性能调优时,调整DB_BLOCK_BUFFERS大小是很重要的一部分。参数DB_BLOCK_SIZE的大小由DB_BLOCK_SIZE和DB_BLOCK_BUFFER相乘到。DB_BLOCK_SIZE是指缓冲区中可放的物理块的大小,即数据库一次I/O访问的大小。从Oracle 10g之后,数据库缓冲区大小由Oralce自动调整。

数据库缓冲区有三种类型:Dirty Buffer、Pinned Buffer、Free Buffer。Dirty Buffer是已被修改需要写回磁盘的数据块,Pinned Buffers是正被访问的数据块,Free Buffer是闲空数据块。

Oracle为了便于管理缓冲区,将缓冲区数据块连成两个队列:写队列和LRU队列。写队列中的数据块排队等待被写回磁盘。Oracle修改数据之后,并不是立即将数据写回磁盘,而是累积到一定数量后才回写。LRU队列又称为最近最少使用队列,由Free Buffers、Pinned Buffers以及没有加入到写队列的Dirty Buffer组成。所谓最近最少使用队列就是将经常使用的数据块放在队首,将最补经常使用的放在队尾,当有新的数据块要加入时,则最先淘汰最不经常使用的队尾数据块。

Oracle将数据缓存区划成三个区域:KEEP、RECYCLE、DEFAULT。KEEP区中的内容能长期驻留,数据块不会被淘汰出去。这个区域的大小由BUFFER_POOL_KEEP决定。RECYCLE区中存储很少使用的数据,该区的内存可直接回收,其大小由BUFFER_POOL_RECYCLE决定,剩余的缓冲都属于DEFAULT区。

3)重做日志缓存区

用户通过insert、update、delete、create、alter、drop等sql命令更改了数据库后,服务器进程会将这些修改记录到重做日志缓冲区内,这些修改记录也叫重做记录(entry)。数据库发生崩溃后,用户可从重做日志缓冲区读取修改记录恢复数据库。重做日志缓冲区记录了发生修改的块、修改的位置,以及修改后的新值。注意,重做记录只记录每一个修改,并不记录发生修改的块类型,所以不能区分修改是在数据块上还是在回滚或索引段上。

重做日志缓冲区是一个循环缓冲区,缓冲区在被覆盖之前会由后台进程LGWR(日志写入进程)将缓冲内容写入联机重做日志文件,所以Oracle数据库对数据库的每次更改都有记录。重做日志缓冲区的大小由初始参数LOG_BUFFER决定。

4)共享池

共享池包括库高速缓冲(library cache)和数据字典缓冲(data dictionary cache)

(1)共享sql区

Oracle将执行过的SQL分成两部分:共享SQL区和私有SQL区。当用户执行SQL语句时,Oracle会将最近执行过的SQL语句的文本、编译后的语法分析树和执行计划(指要完成一条SQL语句,Oracle服务器所需具体实施的步骤)存入共享SQL区,而将SQL语句中的变量值存入私有SQL区(在共享服务器中存入私有SQL区,在专用服务器中存入PGA内)。当服务器再次执行相同SQL语句时,服务器进程将不再对这条语句执行语法分析,而是直接执行SQL共享区中已存在的内容。这种方式有利于提高数据库性能。

注意,这里的相同是指语句完全相同,即语句结构相同,大小相同,变量值相同,否则Oracle服务器会认为不同语句。

(2)私有SQL区

私有SQL区中存放的是SQL语句执行时与每一个会话有关的私有数据,如连接变量的值。专用服务器内私有SQL区存在PGA中;共享服务器内私有SQL区存在共享池中。

(3)共享PL/SQL区

Oracle处理PL/SQL程序与处理SQL语句的方法相同。执行一个PL/SQL程序单元时,Oracle将程序单元放入共享PL/SQL区,而将程序单元内的SQL语句放到共享SQL区中;当再次需要执行相同的程序单元时,就直接从内存中调用,而不需访问磁盘。

(4)控制结构区

这是供实例内部使用的一段内存区,存放了锁、锁存器等方面的信息。

5)数据字典缓冲区

数据字典缓冲区是共享池的一部分,又称为字典区或行缓冲区,它包含了数据库的结构、用户信息和数据库的表、视图等信息。数据字典缓冲区存储了数据里面所有表和视图的名字、数据库基表的列名和列数据类型以及所有Oracle用户的权限等。

字典缓冲区对数据库性能影响很大。在执行SQL语句过程中,服务器进程会经常访问数据字典缓冲区。如果缓冲区太小,数据库就会因为在缓冲中找不到所需信息而反复通过I/O从磁盘获取,严重影响系统性能。

6)程序全局区PGA

PGA(程序全局区,Program Global Area)包括会话信息、堆栈空间、排序区,以及游标状态。会话信息存放的是会话的权限、角色和会话性能统计信息,堆栈空间内存放的是变量、数组和属于会话的其他信息,排序区则是用于排序的一段专用空间,游标状态存放的是当前使用的各种游标的处理阶段。

用户进程连接到Oracle数据库后,服务器创建会话,同时分配一个PGA区。一个PGA区由一个Oracle用户进程所使用,不能共享。对专用服务器(一个数据库连接对应一个专用服务器进程),PGA保存堆栈空间信息和会话信息、游标状态、排序区保存在SGA中。

初始化参数PGA_AGGREGATE_TARGET可以改变PGA的大小。PGA_AGGREGATE_TARGET是指所有服务器进程PGA占用内存的大小之和,它随服务器进程一起产生和释放。

7)排序区

排序区(Sort Area)是给所要排序的sql语句提供的专用内存空间。

如果内存不够,Oracle会将数据分割成很多小块放到排序区内,然后对每个小块分别进行排序。排序过程中Oracle将排序区存放不下的数据存放到磁盘临时段中,最后将这些小段合并起来返回给用户进程。在排序过程中,排序区的大小就是动态变化的,但最大不能超过参数SORT_AREA_SIZE的值。

8)软件代码区

软件代码区用于存储Oracle系统程序和用户程序正在执行或可以可以执行的程序代码。软件代码区是只读的,可以安装成共享或非共享两种形式。Oracle系统程序是可共享的,用以使多个Oracle用户可存取。用户程序可以设为共享也可以设为不共享。Oracle系统程序与用户程序不同,前者存放在软件代码区中较为安全的地方。

软件代码区的大小一般是固定的,只有在软件进行修改或重新安装时才能由操作系统改变大小。在支持多例程Oracle中,同一台机器上运行的几个数据库可以使用同一个代码区。

9)大池

大池(Large pool)是一个可选内存区,从9i版本数据库开始,大池大小由参数LARGE_POOL_SIZE决定;但Oracle 10g版本数据库以后,Oracle自动调整大池大小。在以下几种情况下我们要使用大池;使用共享服务器、执行备份和恢复操作、使用I/O Slaves(要配置DBWR_IO_SLAVES参数)。大池主要为一些需要消耗大量内存的操作提供更大内存空间。

10)java池

java池内存储了java语句的文本、语法分析表等信息。java池为java的命令提供语法分析,从Oracle 9i版本数据库开始,java池大小由参数JAVA_POOL_SIZE决定;但Oracle 10g版本数据库以后,Oracle自动调整大小。如果要安装java vm,用户就必须启用java池。

11)streams池

streams池的主要功能是存放消息(message)。池中存放的消息是共享的,streams的消息可以从一个数据库传播到另一个数据库。利用streams池管理消息比原来捕获和管理消息更容易。

用户可以在SGA中分配streams池。streams池大小通过初始化参数STREAMS_POOL_SIZE分配。如果没有设置这个参数,Oracle在streams第一次使用时会自动创建streams池。

欢迎关注“自学Oracle”

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180126G0HRWD00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券