共享池
共享池为SGA的组成部分,负责缓存各种类型的程序数据。例如,共享池缓存已解析的SQL、PL/SQL代码,系统参数以及数据字典信息。
共享池被划分为如下几个组成部分:
库缓存:用于存储可执行的SQL及PL/SQL代码。该缓存包含共享的SQL和PL/SQL区域以及控制结构,例如锁和库缓存句柄等。当执行SQL语句时,数据库会尝试使用之前执行过的代码。如果库缓存中存在该SQL语句的已解析表现形式而且可以共享,则数据库将会重用代码。该操作称之为软解析,或者库缓存命中。否则,数据库将需要重新构建应用程序的新的可执行版本,这称之为硬解析,或者库缓存未命中。
保留池:Oracle使用该内存区来分配连续的大块内存。数据库从共享池中以块(chunk)的形式分配内存。由于保留池的存在,就可以将大型对象(大于5KB)加载进来,而无需分配单个连续的区域,从而减少了由于碎片化而导致连续内存耗尽的可能性。
字典缓存:存储关于数据库对象的信息(即字典数据)。该缓存也称之为行缓存,因为它将数据保存为行。
服务器结果缓存:用于保存结果集。服务器结果缓存,包含SQL查询结果缓存,以及PL/SQL函数结果缓存,它们共享相同的基础结构。SQL查询结果缓存,用于缓存查询和查询片段的结果,大多数应用的性能都受益于此。PL/SQL函数结果缓存,则缓存存储函数的结果集。结果缓存适用的候选者,往往是经常调用的函数,且这些函数依赖于相对静态的数据。
其他组件:包括队列、闩(latch)、信息生命周期管理(ILM)的位图表、活动会话历史记录(ASH)缓冲区,以及其他次要内存结构。队列是共享的内存结构(锁),用于序列化对数据库资源的访问。它们可以与会话或者事务关联。示例包括:控制文件事务、数据文件、实例恢复、介质恢复、事务恢复,以及作业队列等等。latch则作为低级的序列化控制机制,用于保护SGA中的共享数据免于被同时访问。示例包括:行缓存对象、库缓存pin,以及日志文件的并行写入等。
large pool
large pool是数据库管理员可以配置的可选内存组件,从而如下各项提供大型内存分配:
用户全局区(UGA):共享服务器和Oracle XA接口的会话内存(即分布式事务)。
I/O缓冲区:I/O服务器进程、并行查询操作中使用的消息缓冲区、RAMN操作中I/O进程使用的缓冲区,以及高级队列的内存表。
延迟插入池:Fast Lookup特性,可以操作那些进行了MEMOPTIMIZE FOR WRITE设置的表,从实现单行数据的高频插入(面向IoT应用)。Fast Ingest也被称之为延迟插入。它们最初在large pool中缓存,然后在每个对象的会话中,每次写入1MB,或者60秒之后,由SMCO(Space Management Coordinator,空间管理协调器进程)和Wxxx worker后台进程异步写入磁盘。在SMCO这一后台进程进行扫描之前,任何会话(包括写入数据的会话)都无法读取该缓冲区中缓存的所有数据,即便是这些数据已经提交完毕。该池在large pool中的表进行第一行数据插入的时候被初始化,如果空间足够,则从large pool中为其分配2GB的空间。如果large pool中没有足够的空间,则会在清理数据并报告ORA-04031错误。然后使用一半的空间请求进行重新分配。如果空间还是不够,则会继续使用512MB和256MB再次进行尝试。如果还不成功,则禁用该特性,直到数据库实例重启为止。在对该池进行初始化之后,其大小将会保持不变,无法进行增长或者收缩。
自由内存
large pool与共享池中的保留空间不同,共享池中的保留空间,与共享池中的其他内存空间一样,均使用LRU列表。large pool没有LRU列表。一旦内存分配完毕,将无法再此进行调整,除非已分配的内存使用完毕,其对应的内存空间才会释放。
来自用户的请求,可以是单个API调用,为用户SQL中的一部分。在专用服务器连接模式下,一个服务器进程处理一个客户端进程的请求。每个服务器进程都将会使用系统资源,包括CPU周期和内存。而在共享服务器连接模式下,则将会发生如下操作:
客户端应用向数据库实例发送请求,dispatcher进程接收该请求。
dispatcher进程将该请求放置在large pool中的请求队列上。
下一个可用的共享服务器进程将会处理该请求。共享服务器进程会检查公共请求队列中是否有新的请求,并以先进先出的方式处理请求。一个共享服务器进程处理请求队列中的一个请求。
共享服务器进程对数据库进行所有必要的调用,以处理请求。首先,共享服务器进程访问共享池中的库缓存,以对请求的内容进行验证。例如,它会检查表是否存在,用户是否具有正确的权限等等。接下来,共享服务器进程将会访问db buffe cache,以检索数据。如果数据不存在,那么共享服务器进程将需要访问磁盘。不同的共享服务器进程可以处理每个数据库调用。因此,解析查询、获取第一行数据、获取下一行,以及关闭结果集的请求等,可能会由不同的共享服务器进程处理。因此,用户全局区(UGA)就必须得是共享内存区域,因为UGA中包含了所有客户端会话的信息。或者相反,UGA由于包含了每个客户端会话的信息,因此必须能够为所有的共享服务器进程所访问。
请求处理完毕后,共享服务器进程会将响应放置在large pool中的响应队列中。每个dispather程序都有自己的响应队列。
响应队列将响应发送给dispatcher程序。
dispatcher程序将完成的请求返回给对应的客户端程序。
db buffer cache
db buffer cache,也称之为缓冲区高速缓存,是SGA中的存储区域,用于缓存从数据文件中读取的数据块的副本。缓冲区是以数据库块为基础进行分配的内存块。每个缓冲区都有一个数据库缓冲区地址(DBA,database buffer address)。同时连接到数据库实例上的所有用户,共享对db buffer cache的访问。引入db buffer cache的目标,就是为了优化物理I/O,将经常访问的块保留在内存中,不经常访问的块则写入磁盘。
Oracle数据库的用户进程在第一次需要特定的数据时,将首先在db buffer cache中进行检索,如果该数据已缓存(缓存命中),则直接从内存中读取数据。如果在缓存中找不到(缓存未命中),则需要在访问数据之前,先将数据块从磁盘复制到db buffer cache中。通过缓存命中方式访问数据,要比缓存未命中快得多。
db buffer cache中的缓冲区由复杂的算法进行管理,该算法为LRU列表和touch count的结合。LRU有助于确保最近使用的块倾向于保留在内存中,从而最大程度地减少对磁盘的访问。
db buffer cache包含如下部分:
默认池:默认缓存数据块的位置,块默认大小为8KB。除非您手动配置其他的池,否则默认池就是唯一的缓冲池。其他池的可选配置均对默认池无效。
保留池:适用于经常访问但由于空间不足而在默认池中过期的块。保留池的目的,是在内存中保留指定的对象,从而避免I/O操作。
回收池:用于不经常使用的块。回收池可防止指定的对象占用缓存中不必要的空间。
非默认缓冲池:适用于2KB、4KB、16KB和32KB等非标准块大小的表空间。每个非默认大小的块都有其自己单独的池。这些池的管理方式与默认池相同。
数据库智能闪存缓存(闪存缓存):您可以使用闪存设备来增加buffer cache的大小,而无需增加更多的主内存。闪存缓存可以将数据库缓存的频繁访问数据存储到闪存中,而不是从磁盘中读取,以此来提高数据库的性能。当数据库请求数据时,系统首先会在db buffer cache中查找。如果找不到数据,则继续在闪存缓存中查找。如果还找不到,才会去读取磁盘。对于Oracle RAC环境而言,如果要配置闪存缓存,要么所有实例都配置,要么都不配置。
LRU列表:包含了指向脏缓冲区和非脏缓冲区的指针。LRU列表有一个热端和一个冷端。冷缓冲区是最近未使用过的缓冲区,热缓冲区则是经常被访问且最近已经使用过的。从概念上讲,只有一个LRU列表。但是对于数据并发而言,数据库实际上使用了多个LRU列表。
检查点队列
flash缓冲区:由DEFAULT Flash LRU和KEEP Flash LRU两个链表组成。如果没有数据库智能闪存缓存,则当进程尝试访问某个数据块,并且该块在缓冲区中不存在的话,则需要先将该块从磁盘读入内存(物理读取)。当db buffer cache已满时,将根据LRU机制将缓冲区从内存中逐出。而一旦使用了数据库智能闪存缓存,则当干净的内存缓冲区过期时,该缓冲区的内容将通过DBWn进程在后台写入闪存中,并且缓冲区的头部信息,将会作为元数据保留在DEFAULT Flash LRU和KEEP Flash LRU链表中,具体则取决于对象的FLASH_CACHE属性的设置。KEEP Flash LRU链表用于将缓冲区头部信息保留在单独的列表中,以防止常规的缓冲区头部可以替换它们。因此,指定为KEEP的对象的缓冲区头部信息,倾向于在闪存缓存中保留更长的时间。如果将对象的FLASH_CACHE属性设置为NONE,则系统将不会在闪存缓存,或者是内存中保留相应的缓冲区。当再次访问已过期的内存缓冲区时,系统将会检查闪存缓存。如果找得到,则从闪存缓存中将其读回,这样操作所花费的时间将会比读取磁盘少很多。RAC环境下的闪存缓存,其数据一致性,与缓存融合(cache fusion)的维护方式相同。由于闪存缓存是扩展缓存,而直接路径I/O操作则绕过了db buffer cache,因此它也不支持直接路径I/O。请注意,系统不会将脏缓冲区放入闪存缓存,因为只有在内存中的缓冲区才会对其进行检查点操作,而闪存缓存中的数据不会进行检查点操作。