内存结构,如下图:
一、SGA
SGA组件除了Log buffer之外,空间的分配与释放所基于的基本单位都是granules,granules的大小是基于操作系统和SGA的大小。
1、Database Buffer Cache
Database Buffer Cache也叫buffer cache,保存从数据文件中读取的数据块。buffer cache可以实现下面两个目标:
- 优化物理I/O:当语句COMMIT之后,redo records会被刷新到日志文件中,但是脏缓存并不会马上被刷新到数据文件中,而是保存在buffer cache中。DBWn进程会每三秒刷新一次脏缓存到数据文件。
- 把频繁使用的数据块保存到buffer cache中,把不是很频繁使用的数据块刷新到数据文件中:当Database Smart Flash Cache (flash cache) 启用的时候,部分的buffer cache被保存到flash cache。flash cache位于叫flash disk device的固体状态存储设备。这样就避免了从磁盘中读取数据,而是从flash memory中读取。不过,Database Smart Flash Cache只是用于 Solaris 和 Oracle Enterprise Linux操作系统。
1.1、Buffer States
有三种状态:
- unused:该状态下的缓存数据块没有被使用过;
- Clean:拥有数据但是处于一致性状态,也就是已经被刷新到了数据文件,CKPT不会对其进行检查点操作;
- Dirty:还没有被刷新到数据文件的脏缓存。
每个缓冲块都有两种访问方式:pinned或free.多个会话不能同时对处于pinned状态的缓存块进行访问。为了更有效率地访问数据库缓存,ORACLE使用 least recently used (LRU) list,一端的cold buffer不会经常被访问,而另一端的hot buffer则会经常被访问。为了并发性,ORACLE 会用多个least recently used (LRU) list。
1.2、Buffer Modes
- Current mode:也叫db block get ,数据库经常在修改操作的时候使用db block get,只会修改当前版本的数据块。
- Consistent mode:也叫consistent read get,当需要读取正在被修改的数据块缓存的时候,会使用undo data来让其访问修改前版本的数据块。
1.3、Buffer I/O
- Buffer Reads
buffer search如下图:
其中,第一步对buffer cache的检索叫 logical read,第二步对于flash cache的检索叫optimized physical read,而第三步对于磁盘物理文件的读取叫physical read。
若在第一步的时候找到了所需要的缓冲块,则叫cache hit ,否则叫cache miss。可以使用buffer cache hit ratio来衡量数据库不用从磁盘中读取数据块的频率。
- Buffer Writes :DBWn把不常用的脏缓存写入到物理文件中。
- Buffer Touch Counts:该机制用来描述LRU LIST数据缓存块被访问的频繁程度,若一缓存块被spin而不是constantly shuffling buffers 则该缓存块的touch count增加一次。需要注意的是,在缓存块发生spin的三秒钟之后才会使得touch count增加。该机制避免了burst of pins。比如说,对同一数据块插入多行也只是视为发生了一次touch。若一数据缓存块在LRU LIST的cold端,而其touch count非常高,则该块的指针就会修改到LRU LIST的hot端。数据库不会移动缓存块的位置,而是修改LRU LIST的位置指针。
- Buffers and Full Table Scans:当必须从数据文件中读取数据的时候,数据库会插入这些缓存块到LRU LIST的中部,这样可以避免需要重新从数据文件中读取那些被频繁使用的数据块。当时,对于全表扫描,如果扫描所读取的数据块比数据块缓存还要大,则会导致频繁使用的数据缓存块被覆盖重写。此时,数据库对于全表扫描采用了不同于其他的一种方式,全表扫描的这些数据块会马上被重用,以避免清空缓存问题的出现。不过,如果默认的行为并不是你所想要的话,可以在创建表的时候设置CACHE参数。此时,数据库不会pin the blocks.
1.4、Buffer Pools
Buffer Pools 是一组缓冲的集合。database buffer cache被分成一个或多个buffer pools.如下图:
- Default pool:读入的数据块正常情况下会被缓存在这里;
- Keep pool:其是为那些经常被访问的缓存数据块所留的,不过当空间不足的时候会age out Default pool。其目的是保留这些对象在内存中,从而避免不必要的I/O操作;
- Recycle pool:其是为那些经常被使用的缓存数据块所预留的。其可以避免这些对象消耗不必要的空间。
- 另外还有一些数据块大小不是DB_CACHE_SIZE大小的数据块保存区域。
2、Redo Log Buffer
redo log buffer保存了DDL或DML语句所产生的redo records。LGWR总是先于DBWn把redo records写入到online redo log中。
3、Shared Pool
3.1、Library Cache
正如上图所示Library Cache包括了shared SQL area和private SQL area(只是在shared server模式下存在)两部分。其中,Library Cache保存的是解析的SQL语句、解析树、执行计划和PL/SQL程序单元。
当一个新的SQL语句被解析的时候,数据库就会为其分配新的shared pool内存,分配的大小取决于语句的复杂度。
在下面的情况下,一个SQL语句的shared SQL area的内存空间会被删除或无效。
- LRU中所对应的最不常被使用的shared SQL area的内存就会被释放;
- 如果统计数据是从表、聚集表或索引中收集来的,在默认情况下数据库会在一段时间之后逐步删除包含对象的shared SQL area内存空间;
- 如果SQL语句所引用的对象由于DDL语句被修改了定义,则这些shared SQL area就会无效;
- 如果你改变了数据库的global name,则整个shared pool都会被清空;
- ALTER SYSTEM FLUSH SHARED_POOL语句的提出;
3.2、Data Dictionary Cache:以row cache的方式(而不是buffer)保存用过的数据字典对象;
3.3、Server Result Cache
在这里,其保存的是结果集而不是数据块。
- SQL Query Result Cache:保存的是SQL语句的结果,当有事务修改了构成该结果集对象的数据或元数据,则相应的结果集将会变成无效。可以在语句中使用RESULT_CACHE hint来指示数据库语句使用其中的结果集。而RESULT_CACHE_MODE则决定了SQL Query Result Cache是由所有的语句使用,还是只是哪些添加了注释的语句所使用;
- PL/SQL Function Result Cache:保存函数的结果集(对应参数和结果集),如果形成结果集的对象被修改了,则相应的结果集也会无效,需要重新计算。
另外,需要注意的是,client result cache是应用程序级别的结果保存。其保存在客户端。
3.4、Reserved Pool
该内存的作用用技术文档的话语来说就是allocate large contiguous chunks of memory。以chunk的形式,可以允许大对象(超过5KB)被加载到内存而不是请求一个临近区域。这种方式可以避免因为碎片而用完临近内存的情况出现。在很少情况下,Java, PL/SQL, 或者SQL cursors会要求超过5KB的共享池内存。为了让这些分配的空间更有效,数据库会分割一些shared pool给Reserved Pool。
4、Large Pool
大池可以为下面的操作或结构提供大量的空间:
- 共享服务器模式下的UGA结构,还有就是Oracle XA接口;
- 并发执行语句的信息缓存;
- RMAN I/O slaves;
大池不是根据LRU LIST来释放内存。大池中的内存被分配之后直到不在被使用。为此,会有大量的内存被释放,其他进程就可以使用。
5、Java Pool
Java Pool保存的数据为JAVA代码以及JVM中的数据。
6、Streams Pool
Streams Pool为ORACLE流所使用,其存储的是缓冲队列信息,同时为ORACLE stream捕获进程和应用进程提供内存空间。
7、Fixed SGA
Fixed SGA是一个内部管理区域。比如,Fixed SGA包括下面的内容:
- 关于数据库和实例状态的通用信息;
- 进程间的通讯信息,如LOCK;
8、Software Code Areas
Software Code Areas用来存储正在运行或能够被运行的代码,如ORACLE DATABASE CODE.
二、PGA
1、private SQL Area
当会话开始的时候,会产生一个cursor,该cursor是PGA中private SQL Area的名称或handle,可以理解为其实客户端的一个指向服务器端的指针,以及在服务器端的一个声明。该区域有客户端负责管理,虽然服务器端有OPEN_CURSOR实例参数来限制会话的数量。
- The run-time area:执行请求的第一步就是创建The run-time area,来保存该SQL语句以及语句被执行的状态信息,如全表扫描所查找行的数目;该区域在SQL语句结束的时候被释放;
- The persistent area:该区域保存了会话期间所有的bind variable.该区域在会话结束的时候被释放。
2、Session Memory:即下面要说的UGA,存在于detected server模式中。
3、SQL Work Areas
- Sort Area:对行集进行排序;
- Hash Area:hash join操作会使用Hash Area来创建hash table;
- Bitmap Merge Area:Bitmap Merge操作使用Bitmap Merge Area操作来合并从Bitmap index中查找到的数据;
三、UGA:
以上为UGA的结构主件。UGA是一个会话内存,其必须在整个会话周期内有效。为此,在shared server模式下,必须在SGA中,因为PGA对应的是一个进程,该进程是对应多个会话的。而在dedicated server模式下,其存在于PGA中。如上图所示,UGA中包括了两部分的信息:
- Session Variables:为一个会话所需要的信息,如logon信息等。若该会话调用了PL/SQL包,则UGA会包括package state,即在某一特定时间包的参数值;
- OLAP Pool:当用户访问维度对象如cube的时候,一个OLAP会话就已经自动启动,同时会在OLAP Pool中分配OLAP page(相当于data block),以保存相关的信息,该OLAP page会在会话期间一直存在。
如有错误,欢迎指正
技术交流QQ:1732035211
技术交流邮箱:1732035211@qq.com
新浪微博:数据库小菜鸟http://weibo.com/u/3132578390