基本内存结构

                                                                                     基本内存结构
SGA:SGA是一组称为SGA组件的共享内存结构,其中包含了一个ORACLE数据库实例的数据和控制信息。SGA由所有服务器进程和后台进程共享。
例如:SGA中存储的数据包括数据块缓存和共享SQL区。
PGA:PGA是一个非共享的内存区域,其中包含专门供某个ORACLE进程使用的数据和控制信息。oracle进程启动时,oracle数据库会为其创建
PGA。每个服务器进程和后台进程都存在一个PGA。所有单个PGA的集合即使总实例PGA或实例PGA。数据库初始化参数设置实例PGA的大小,而
不是单个PGA的大小。
是一个特定于一个操作消停进程或线程的内存区,且不和系统上的其他进程或线程共享。由于PGA是特定于进程的,所以它决不会在SGA中分配
PGA是包含某个专用或共享服务器进程所需的会话变量的内存堆。服务器进程在需要时会在PGA中分配内存结构。
PGA好比是文员使用的临时工作台面。文员就是客户服务的服务器进程。
UGA:是与某个用户会话相关联的内存区;是未会话变量分配的会话内存,如登录信息和数据库会话所需的其他信息。
如果某个会话将PL/SQL包加载到内存,则在UGA中包含包状态,即是所有包变量在某个特定的时刻所存储的值集。当包的子程序更改变量的值
时,包状态也将更改。默认情况下,包变量在会话的存活期间是唯一且持久的。
OLAP页面缓冲池也存储在UGA中。该池管理相当于数据块的OLAP数据页面。页面缓冲池在启动一个OLAP会话时分配,并在该会话结束时释放。
每当用户查询一个多维对象(如立方体)时,就会自动打开一个OLAP会话。
该UGA必须在数据库会话的整个存活期间是可用的。由于这个原因,当使用共享服务器的连接时,UGA不能存储在PGA中,因为PGA是特
定于单个进程的。因此,当使用共享服务器的连接时,UGA被存储在SGA中,以使任何共享服务器进程都能访问它。在使用专用服务器的连
接时,UGA存储在PGA中。
软件代码区:是用来存储正在运行或可能要运行的代码的那部分内存。oracle数据库代码通常存储在与用户程序不同的位置。


PGA被划分为下面几个部分:
private SQL area:
保存了有关某个已解析的SQL语句的信息,和其他特定于会话的信息。当服务进程执行SQL或PL/SQL代码时,该过程使用其私有SQL区域,来存储
绑定变量值、查询执行状态信息、和查询执行工作区。

这里注意不要混淆在UGA中的私有SQL区,和在SGA中存储执行计划的共享SQL区。在相同或不同的会话中的多个私有SQL区,可能指向SGA中的一个
单一执行计划。例如,在某个会话中运行“SELECT * FRM EMP;"20次,而在另个不同的会话中运行同一查询10次,但他们可以享受相同的执行计划。
每次运行的私有SQL区并不共享,因此可能包含不同的值和数据。

游标是指向某个特定的私有SQL区的一个名称或句柄。你可以将游标看成是一个从客户端指向服务器端状态信息的指针。游标与私有SQL区密切相关,
这两个术语有时可以互换使用
private sql area又可细化如下两个区域
persistent area:此区域包含绑定变量的值。绑定变量是执行SQL语句时,在运行时提供给SQL语句的值。仅当关闭该游标时,persistent area才
被释放
runtime area:此区域包含查询执行状态信息。例如,运行时区域会跟踪到目前为止在全表扫描中检索到的行数;oracle数据库将创建运行时区域,
作为一个执行请求的第一部。对于DML语句,其运行时区域将在SQL语句关闭时被释放。

客户端进程负责管理私有SQL区。虽然客户端进程可以分配的私有SQL区数量由初始化参数OPEN_CURSORS限制,但私有SQL区的分配和释放主要取决
于应用程序。

虽然大多数用户依靠数据库实用程序的游标自动处理机制,但是oracle数据库编程接都仍为开发人员提供了对游标更多的控制。一般情况下,应用
程序应关闭所有打开的且不再实用的游标,以释放持久区域,并最小化应用程序用户的内存需求。

SQL WORK AREA:是在PGA中为内存密集型操作分配的私有内存区。例如:排序操作实用排序区来对一组进行排序。同样,哈希联接操作将其左侧数据
作为输入,并使用哈希区来创建一个hash table。

专用和共享服务器模式中的PGA
内存区                            dedicated  shared
会话内存的性质                      private   shared
Location of the persistent area     PGA         SGA
Location of the run-time area       PGA         PGA
for DML/DDL statements

SGA:
除重做日志缓冲区外,所有 SGA 组件按称为颗粒的连续内存单元来分配和释放空间。颗粒大小是特定于平台的,由 SGA 的总大小决定。
1、Database Buffer Cache;The database buffer cache, also called the buffer cache
用于存储从数据文件读取的数据块副本的内存区域。缓冲区时缓冲区管理器用来暂时缓存当前或最近使用的数据块的主内存地址。所有同时都连接到一个
数据库实例的用户,以共享方式访问缓冲区告诉缓存。

为什么会使用buffer cache呢?
优化物理I/O
  数据库更新缓存中的数据块,并将有关更远的元数据存储在重做redo log buffer。提交后,数据库将buffer cache到磁盘,但不一定立即写数据
块到磁盘。相反,DBWn在后台执行惰性写入操作
  将频繁访问的块保持在缓冲区告诉缓存中,而将不常存取的块写到磁盘
当启用了Database Smart Flash Cache (flash cache),buffer cache的一份可能驻留在闪存缓存中。此缓冲高速缓存扩展存储在内存磁
盘设备上,这是一种使用闪存的固态存储设备。通过将缓冲区缓存到闪存中,而不是从磁盘读取,数据库可以提高性能。

buffer states:
数据库使用内部算法来管理buffer。可以处理一下状态
未使用:可供使用,因为它从未使用过,或者当前未使用。这种类型的缓冲区是数据库最容易使用的
干净:之前曾被使用过,而现在包含某个数据块在某个时间点的读取一致版本。块包含数据但是干净的,因此它不需要将执行检查点操作。
数据库可以pin该块并重用它。
脏:包含已修改,但尚未写入到磁盘的数据。数据库在重用该数据块之前必须对其执行检查点操作。

每个buffer具有两种访问模式之一:pinned or free。bffer cache被pinned在缓存中,以便当其被某个用户会话访问时,他不会因为
内存不足被患处内存。多个会话不能再同一时间修改某个被pinned的缓冲区

数据库使用复杂的算法以使buffer访问,least recently used (LRU) list有个冷端和热端,同时存在指向同一LRU上的脏缓冲区和非脏缓冲
区的指针。冷缓冲区是最近未被使用的。热缓冲区是被频繁访问并在最近已使用的。

buffer modes:
下面两种方式查询方式来给请求的数据
当前模式获取,也称为数据库块获取,这是一种对当前已出现在缓冲区高速缓存中的块的检索。例如,如果一个未提交事务已更新某
个块中的两行,则当前模式获取会检索这个具有未提交行的块。数据库最常使用数据库块获取的情况是在修改语句期间,它只需更新
块的当前版本。

一致读取获取是对某个块的一致读取版本的检索。此检索可能会使用undo数据。例如,如果一个未提交事务已更新某个块中的两行,
而在另一个独立会话中的查询请求该块,则数据库使用undo数据来创建该块的一个读取一致版本(称为一致读取克隆),它不包括未
提交的更新。通常,查询以一致模式检索块。

buffer I/O(logical I/O)指的是读取和写入缓冲区高速缓存中的缓冲区。当在内存中找不到请求的缓冲区时,数据库将执行一个物理
I/O,将缓冲区从闪存缓存或磁盘复制到内存,然后再执行一个逻辑 I/O,以读取缓存的缓冲区。

buffer writes
数据库写入器(DBWn)进程定期将冷的、 脏的缓冲区写入磁盘。DBWn在以下情况下会将缓冲区写出:
1.服务器进程找不到干净的缓冲区,以将新块读入数据库缓冲区高速缓存。
2.随着缓冲区变脏,可用缓冲区的数量就会减少。如果该数值低于一个内部阈值,而又需要干净的缓冲区,则服务器进程将通知DBWn
执行写出操作。
3.数据库使用LRU来确定哪些脏缓冲区被写出。当脏缓冲区到达LRU 的冷端时,数据库将其从LRU上移出到写出队列。DBWn 将队列中的
缓冲区写到磁盘,如果可能使用多块写,则用之。此机制可以防止LRU尾端被脏缓冲区塞满,并保证有干净的缓冲区可供重用。
4.数据库必须推进检查点,即重做线程中进行实例恢复的起点。
5.表空间被更改为只读状态,或脱机。

buffer reads
当干净的或未用的buffer的数量变的很少时,数据库就必须将某些buffer从buffer cache删除。
如果Flash cache disabled
数据库中根据需要覆盖并重新利用每个干净的buffer。如果以后需要重用被覆盖的buffer,则数据库必须从磁盘重新读取
如果Flash cache enabled
DBWn将干净buffer正文写入到flash cache,使其内存中的缓冲区可以被重用。数据库在主内存中保留 LRU 列表的缓冲区头,以跟踪在闪
存缓存中的缓冲区体的状态和位置。如果以后需要该缓冲区,则数据库可以从闪存缓存中读取它,而不用从磁盘读取。

当客户端进程请求一个buffer时,服务器进程在buffer cache中搜索buffer。如果数据库在memory里找到了buffer,则发生cache hit。
1.服务器进程在buffer cache中搜索buffer
如果该进程发现整个buffer,则数据库对此buffer执行一个逻辑读取
2.服务进程在flash cache LRU列表中搜索buffer header
如果该进程找到了buffer header,则数据库执行一个优化的物理读取,将buffer正文从flash cache读入到memory cache中。
3.如果该进程没有在内存中找到该缓冲区,则服务器进程
a.物理读从数据文件到内存中
b.对已读入到内存中的缓冲区执行一个逻辑去读

一般情况下,通过缓存命中访问数据比通过缓存未命中要快。缓冲区高速缓存命中率用于测量数据库在缓冲区高速缓存中找到请求的块,而不
需要从磁盘中读取的比率。

数据库可能从数据文件或临时文件执行物理读取。在数据文件读取之后,会紧跟着有逻辑I/O。临时文件读取发生在当内存不足时,迫使数据
库将数据写入一个临时表,稍后又将其读回。这种物理读取会绕过缓冲区高速缓存,并不会导致逻辑的I/O。

Buffer Touch Counts
数据库使用触摸计数来测量对 LRU 列表上的缓冲区进行访问的频率。这种机制使得当某个缓冲区被订住时数据库可以增加一次计数,而不用不
断地移动LRU列表上的缓冲区。数据库不会物理帝移动内存中的块。此移动只是改变列表上指针的位置。

当buffer被pinned时,数据库将确定其touch counts的最后一次递增是何时发生的。如果计数递增发生在超过3秒钟前,则计数增加1;否则,计数
保持不变。三秒钟规则防止对该buffer的一系列突发pinned产生过多计数。例如,一个会话肯能个会一个数据块中插入几行,但数据库将这些插入
作为一个touch来看待

如果某个buffer在在LRU的冷端上,但其touch counts很高,则该buffer移动到热端。如果touch counts很低,则buffer会从cache中老化移出

Buffers and Full Table Scans
当缓冲区必须从磁盘读入时,数据库会将buffer插入到LRU列表的中部。通过这种方式热块可以保留在缓存中,以使他们不需要再次从磁盘读取。

全表扫描顺序读取高水位下的所有行,这可能引发一个问题。假设表段中块的总大小大约buffer cache的大小。在此表上的全表扫描可能会清除
除buffer cache,致使数据库不能将频繁访问的块维持在cache中。

大型表的完全扫描导致将块将块读入数据库cache,也其他类型读取的处理方式有所不同。在完成扫描之后,这些缓冲区中的块可以被立即重用。
以防止该扫描真正清理缓冲区高速缓存。

BUFFER POOL:
buffer pool是buffer的集合。数据库buffer cache被划分为一个或多个的buffer pool
可以手动配置多个单独的buffer pool,要么将数据保留在buffer cache中,或在使用了数据块之后、使buffer立即可用于新的数据。然后,可以
将schema对象分配给适当的buffer pool,以控制数据块如何从缓存中老化移出。
Default pool:该池是块通常被缓存的地方。除非你手动配置单独的池,默认池将是唯一的缓冲池
Keep pool:该池用于被频繁访问的块,使其不会犹豫缺省的空间不足而被移出。keep pool的目的是将对象保留在内存中,从而避免I/O操作
Recycle pool:该池用于不被频繁使用的块。循环池防止为对象在缓存中占用不必要的空间。


REDO LOG BUFFER
redo log buffer是SGA中的一个循环式缓冲区,用来存储对数据库所做更改的redo条目。redo条目包含用于重建(或重做)由DML或DDL操作对数据库
所做更改所需的信息。数据库恢复将重做条目应用到数据文件,以重建丢失的更改。Oracle 数据库进程将重做条目从用户内存空间复制到SGA的重
做日志缓冲区中。重做条目占用缓冲区中连续、顺序的空间。日志写入器(LGWR)后台进程将重做日志缓冲区写入磁盘上的活动联机重做日志组。
LGWR进程将重做信息顺序写入磁盘,而DBWRn进程将数据块分散写入磁盘。分散写入往往要比顺序慢的多。LGWR使用用能否避免等待DBWn完成其缓慢
的写入,为数据库提供了更好的性能。
LOG_BUFFER初始化参数指定了Oracle数据库在缓冲重做条目时所能使用的内存量。与其他的SGA组件不同,重做日志缓冲区和固定的SGA缓冲区不按颗
粒划分内存。

SHARED POOL
shared pool缓存各种类型的程序数据。例如:共享池存储已解析的SQL、PL/SQL代码、系统参数、和数据字典信息。几乎数据库中发生的每个操作
都涉及都shared pool。例如:如果用户执行一个SQL语句,则oracle数据库会访问shared pool。

shared pool可以细化成如下组件

library cache:是存储可执行SQL和pl/sql代码的共享池内存结构。此缓存包含共享SQL和PL/SQL区,以及锁和library cache之类的控制结构。
在共享服务器体系结构中,library cache还包含 private sql area
在执行SQL语句事,数据库将尝试重用以前执行过的代码。如果在library cache中存储在该SQL语句的已解析表示形式,并且是可以共享的,则数
据库会重用该代码,这称为soft parse or a library cache hit。否则,数据必须为应用程序代码建立一个新的可执行版本,hard parse or a
library cache miss。
      数据库所运行的每个SQL语句,会存在于下列两种SQL区之一:
      Shared SQL Areas:数据库使用shared sql areas来处理SQL语句第一次发生时的情况。该区域对所有用户可访问,并包含语句的解析树
      和执行计划。对于每个唯一的语句,值存在一个共享SQL区
      Private SQL area:每个发出的SQL语句的会话在其PGA中有一个私有SQL区。提交同一语句中的每个用户都分别有一个私有SQL区,但都指
      向同一共享SQL区。因此,在多个单独PGA中的私有SQL区可能与同一共享SQL区相关联。
当应用程序提交类似的SQL语句时,数据库会自动决定怎么做。数据库会同时考虑从用户和应用程序直接发出的语句,及其它语句从内部发出的
递归SQL语句。
数据库执行以下操作:
1、检查shared pool,看是否存在某个语法和语义上都相同的语句的共享SQL area。
如果存在这样的一个相同的语句,则数据库为该语句的后续新实例使用这个shared SQL area,从而减少内存消耗
如果不存在这样一个相同的语句,则数据库在共享池中分配一个新的共享SQL区。语法相同、但语义不同的语句使用一个子游标。
在这梁红情况下,用户的private sql area区都指向包含语句和执行计划的shared sql area
2、为该会话分配一个private sql area
private sql area的位置取决于该会话所建立的连接。如果会话是通过共享服务器连接的,则该private sql area中的一部分被保存在SGA中。
库缓存包含PL/SQL程序和Java类的可执行形式。这些项目统称为程序单元。
数据库程序单元的处理与SQL语句类似。例如,数据库分配一个共享区域来保存PL/SQL程序的已解析和已编译形式。数据库分配一个私有区
域来保存运行该程序特定于会话的值,包括为执行SQL的本地、全局、包变量、和缓冲区等。如果有多个用户运行同一程序,则每个用户将维
护其私有SQL区的一个单独副本,其中包含特定于会话的值,以访问某个单一的共享SQL区。
数据库按前面所述的那样处理PL/SQL程序单元内的单个SQL语句。尽管它们源于同一 PL/SQL程序单元,这些SQL语句将使用一个共享区
域来保存其已分析的表示形式,并为运行该语句的每个会话使用一个私有区域来保存私有数据。
共享池中的内存分配和重用
当解析新的SQL语句时,数据库将分配共享池内存。内存大小取决于语句的复杂性。
通常,共享池中的项目会一直保留,直到按LRU算法将其移除。数据库允许共享池中用于多个会话的项目被保留在内存中,只要他们还有用,
即使创建该项目的进程已经终止。这一机制能最小化开销和对SQL语句的处理。
如果需要为新项目腾出空间,则数据库会释放内存中不常使用的项目。某个共享的SQL区可能会被从共享池中删除,即使该共享SQL区对
应于一个已打开但已有一段时间未使用的游标。如果随后又需要运行这个已打开的游标,则Oracle数据库重新解析该语句并分配新的共享SQL区。
数据库还在以下情况下从共享池中删除共享SQL区:
1、如果为表、 表簇、或索引收集了统计信息,则默认情况下,数据库在一段时间后,会逐步删除所有包含引用了已分析对象的语句的共享SQL区。
下次运行某个已删除的语句时,数据库将在一个新的共享SQL区中对其进行解析,以反映模式对象的新的统计信息。
2、如果一个模式对象在某个SQL语句中被引用,而之后此对象被某个DDL语句修改,则数据库将使这个共享SQL区无效。当下一次运行该语句时,
优化程序必须重新解析该语句。
3、如果更改了全局数据库名称,则数据库将删除所有共享池信息。
你可以使用ALTER SYSTEM FLUSH SHARED_POOL语句,手动删除共享池中的所有信息,以评估实例重新启动后预期的性能。

data dictionary cache:
数据字典是数据库表和视图的集合,其中包含有关数据库及其结构、用户等参考信息。Oracle数据库在解析SQL语句期间,会频繁访问数据字典。
Oracle数据库如此频繁地访问数据字典,所以指定了以下这些特别的内存位置来保存字典数据:
数据字典缓存:此缓存保存有关数据库对象的信息。此缓存也称为行缓存,因为它按行、而不是按缓冲区保存数据。
库缓存:所有服务器进程都共享这些缓存来对数据字典信息进行访问。

server result cache:
与缓冲池保存数据块不同,服务器结果缓存保存的是结果集。服务器结果缓存包含SQL查询结果缓存和PL/SQL函数结果缓存,它们共享相同的基础结构。
客户端结果缓存不同于服务器结果缓存。客户端缓存在应用程序级别配置,并位于客户端内存中,而不是位于数据库内存中。
SQL查询结果缓存:数据库能在SQL 查询结果高速缓存中存储查询和查询片段的结果,将此缓存结果用于将来的查询和查询片段。大多数应用程序受
益于这种性能改善。
假设应用程序将重复执行相同的 SELECT 语句。如果结果会被缓存,则数据库会将其立即返回。通过这种方式,数据库避免了重读块和重计算
结果等昂贵操作。每当事务修改了数据或用于构造该缓存结果的数据库对象元数据时,数据库自动使其高速缓存结果无效。
用户可以为查询或查询片断添加RESULT_CACHE提示,以指示数据库应将其结果存储在SQL查询结果缓存中。由RESULT_CACHE_MODE初始化参数确定
SQL查询结果缓存将用于所有查询(如果可能)还是仅用于添加了注释的查询。

reserved pool:
保留池是共享池中的一个内存区, Oracle 数据库使用它来分配大的连续内存块。
从共享池中分配内存是按大块执行的。大块使得大型对象(超过 5 KB)可以被加载到缓存中,而不需要一个单一的连续区域。这样一来,数据库中
由于碎片引起的连续内存不足的可能性降低了。
有时,Java、 PL/SQL、或 SQL 游标也可能会从共享池中分配大于 5 KB 的内存块。为使这种分配更有效,数据库从共享池中为保留池隔离出少量
内存。

JAVA POOL/LARGE POOL/STREAM POOL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值