描述SGA 中的内存组件
• 实施自动内存管理
• 手动配置SGA 参数
• 配置自动PGA 内存管理
内存管理:概览
DBA 必须将内存管理视为其工作中至关重要的部分,因为:
• 可用内存空间量有限
• 为某些类型的功能分配更多内存可提高整体性能
• 自动优化的内存分配通常是正确的配置,但特定环境甚至短期情况下可能需要特别注意
由于数据库服务器上的可用内存量有限,因此,对于Oracle DB 实例,必须注意内存的分配情况。如果将过多的内存分配给没有此需求的特定区域使用,则很可能导致其它功能区没有足够的内存,无法以最优方式工作。采用自动确定和维护内存分配的功能,极大地简化了该项任务。但是,要实现系统内存最佳利用,即使是自动优化的内存也需要进行监控,有时可能还需要某种程度的手动配置。
复查Oracle DB 内存结构

复查Oracle DB 内存结构
Oracle DB 创建并使用内存结构来满足多种用途。例如,内存可以存储正在运行的程序代码、用户间共享的数据以及每个已连接的用户的专用数据区域。
一个实例有两个关联的基本内存结构:
• 系统全局区(SGA) :一组共享的内存结构(称为 SGA 组件),其中包含一个 Oracle DB 实例的数据和控制信息。SGA 在所有服务器和后台进程之间共享。SGA 中存储的数据的示例包括高速缓存的数据块和共享SQL 区域。
• 程序全局区(PGA) :包含服务器进程或后台进程的数据及控制信息的内存区域。PGA 是Oracle DB 在服务器进程或后台进程启动时创建的非共享内存。服务器进程对PGA 的访问是独占的。每个服务器进程和后台进程都具有自己的PGA 。
SGA 是包含实例的数据和控制信息的内存区。SGA 包含以下数据结构:
• 共享池:用于缓存可在用户间共享的各种构造
• 数据库缓冲区高速缓存:用于缓存从数据库中检索到的数据块
• 保留缓冲池:一种经过优化的专用数据库缓冲区高速缓存,用于长时间在内存中保留数据块
• 回收缓冲池:一种经过优化的专用数据库缓冲区高速缓存,用于从内存中快速回收或删除数据块
• nK 缓冲区高速缓存:几种专用数据库缓冲区高速缓存之一,用于存放与默认数据库块大小不同的块大小
• 重做日志缓冲区:用来缓存用于恢复实例的重做信息,直到可以将其写入磁盘中存储的物理重做日志文件
• 大型池:可选区域,用于为某些大型进程(如 Oracle 备份和恢复操作)和I/O 服务器进程分配较大的内存空间
• Java 池:用于存储Java 虚拟机(JVM) 中特定会话的所有 Java 代码和数据.
• 流池:Oracle Streams 使用它来存储捕获和应用所需的信息.
使用Oracle EnterpriseManager 或SQL*Plus 启动实例时,会显示为SGA 分配的内存量。
程序全局区(PGA) 是一个内存区,其中包含每个服务器进程的数据及控制信息。Oracle Server 进程为客户机请求提供服务。每个服务器进程都有在服务器进程启动时创建的自己专用的PGA 。PGA 只能由相应的服务器进程访问,并且只有代表该服务器进程的 Oracle 代码可对其进行读取和写入。PGA 分为两个主要区域:堆栈空间和用户全局区(UGA) 。
使用动态SGA 基础结构,可以在不关闭实例的情况下更改数据库缓冲区高速缓存、共享池、大型池、Java 池和流池的大小。
Oracle DB 使用初始化参数来创建和管理内存结构。管理内存的最简单方法是允许数据库自动管理和优化内存。在大多数平台上,要实现此目的,只需设置目标内存大小初始化参数( MEMORY_TARGET ) 和最大内存大小初始化参数( MEMORY_MAX_TARGET)。
缓冲区高速缓存

缓冲区高速缓存
通过指定DB_CACHE_SIZE 参数的值,可以配置缓冲区高速缓存。缓冲区高速缓存可存放数据文件中块大小为DB_BLOCK_SIZE 的数据块的副本。缓冲区高速缓存是SGA 的一部分,因此所有用户都可以共享这些块。服务器进程将数据文件中的数据读入缓冲区高速缓存。为了提高性能,服务器进程有时在一个读操作中会读取多个块。然后由DBW n 进程将数据从缓冲区高速缓存写入数据文件。为提高性能,DBW n 在一个写操作中会写入多个块。
在任何给定时间,缓冲区高速缓存都可能会存放一个数据库块的多个副本。虽然该块只存在一个当前副本,但为了满足查询需要,服务器进程可能需要根据过去的映像信息构造读一致性副本。这称为读一致性(CR) 块。
最近最少使用(LRU) 列表可反映缓冲区的使用情况。缓冲区将依据其被引用时间的远近和引用频率进行排序。因此,最经常使用且最常用的缓冲区将列在最近最常使用一端。传入的块先被复制到最近最少使用一端的缓冲区中,然后该缓冲区将被指定到列表中央,作为起点。从这个起点开始,缓冲区根据使用情况在列表中上下移动。
缓冲区高速缓存中的缓冲区可以处于以下四种状态之一:
• 已连接:当前正将该块读入高速缓存或正在写入该块。其它会话正等待访问该块。
• 干净的:该缓冲区目前未连接,如果其当前内容(数据块)将不再被引用,则可以立即执行过期处理。这些内容与磁盘保持同步,或者缓冲区包含块的读一致性快照。
• 空闲/未使用:缓冲区因实例刚启动而处于空白状态。此状态与“干净”状态非常相似,不同之处在于缓冲区未曾使用过。
• 脏:缓冲区不再处于连接状态,但内容(数据块)已更改,因此必须先通过 DBW n 将内容刷新到磁盘,然后才能执行过期处理。
服务器进程使用缓冲区高速缓存中的缓冲区;而DBW n 进程通过将更改的缓冲区写回数据文件,使高速缓存中的缓冲区变为可用状态。
检查点队列中列出将要写出到磁盘的缓冲区。
Oracle DB 支持同一数据库中有多种块大小。标准块大小用于SYSTEM 表空间。标准块大小可以通过设置初始化参数DB_BLOCK_SIZE 来指定。其有效值介于2 KB 到32 KB 之间,默认值为8 KB。非标准块大小的缓冲区的高速缓存大小通过以下参数指定:
• DB_2K_CACHE_SIZE
• DB_4K_CACHE_SIZE
• DB_8K_CACHE_SIZE
• DB_16K_CACHE_SIZE
• DB_32K_CACHE_SIZE
DB_ n K_CACHE_SIZE参数不能用于调整标准块大小的高速缓存的大小。如果DB_BLOCK_SIZE 的值为n K,则设置DB_ n K_CACHE_SIZE是非法的。标准块大小的高速缓存的大小始终由DB_CACHE_SIZE 的值确定。
由于每个缓冲区高速缓存的大小都有限制,因此,通常并非磁盘上的所有数据都能放在高速缓存中。当高速缓存写满时,后续高速缓存未命中会导致Oracle DB 将高速缓存中已有的灰数据写入磁盘,以便为新数据腾出空间。(如果缓冲区中没有灰数据,则不需要写入磁盘即可将新块读入该缓冲区。)以后若对已写入磁盘的任何数据进行访问,则会导致再次出现高速缓存未命中现象。
数据请求导致高速缓存命中的几率会受到高速缓存大小的影响。高速缓存越大,包含所请求数据的几率也就越大。因此,增加高速缓存大小会提高引起高速缓存命中的数据请求的百分比。
使用多个缓冲池

数据库管理员(DBA) 可以创建多个缓冲池来提高数据库缓冲区高速缓存的性能。你可以根据对象的访问情况将其分配给某个缓冲池。
缓冲池有三种:
• 保留:此池用于保留内存中可能要重用的对象。将这些对象保留在内存中可减少 I/O操作。通过使池的大小大于分配给该池的各个段的总大小,可以将缓冲区保留在此池中。这意味着缓冲区不必执行过期处理。保留池可通过指定DB_KEEP_CACHE_SIZE参数的值来配置。
• 回收:此池用于内存中重用几率很小的块。回收池的大小要小于分配给该池的各个段的总大小。这意味着读入该池的块经常需要在缓冲区内执行过期处理。回收池可通过指定DB_RECYCLE_CACHE_SIZE参数的值来配置。
• 默认:此池始终存在。它相当于没有保留池和回收池的实例的缓冲区高速缓存,可通过DB_CACHE_SIZE 参数进行配置。
注:保留池或回收池中的内存不是默认缓冲池的子集。
CREATE INDEX cust_idx …
STORAGE (BUFFER _POOL KEEP);
ALTER TABLE oe.customers
STORAGE (BUFFER_POOL RECYCLE);
ALTER INDEX oe.cust_lname_ix
STORAGE (BUFFER _POOL KEEP);
BUFFER_POOL 子句用于定义对象的默认缓冲池。它是STORAGE子句的一部分,对CREATE 和ALTER表、集群和索引语句有效。未明确设置缓冲池的对象中的块将进入默认缓冲池。
语法为:BUFFER_POOL [KEEP| RECYCLE | DEFAULT] 。
使用ALTER语句更改对象的默认缓冲池时,已缓存的块会一直保留在其当前缓冲区中,直到正常缓冲区管理活动将它们清除为止。从磁盘读取的块将被放置在为该段新指定的缓冲池中。
由于多个缓冲池被分配给某一个段,所以有多个段的对象可以将块放置在多个缓冲池中。
例如,按索引组织的表在索引段和溢出段上可以有多个不同的池。
共享池
内容:
• 库高速缓存(共享sql区域):命令文本、已进行语法分析的代码和执行计划
• 数据字典高速缓存:数据字典表中各表、列和权限的定义
• 结果高速缓存:SQL 查询和PL/SQL 函数的结果
• 用户全局区(UGA) :Oracle 共享服务器的会话信息
可以使用SHARED_POOL_SIZE 初始化参数指定共享池的大小。共享池是用于存储多个会话共享的信息的内存区。它包含不同类型的数据,
库高速缓存:库高速缓存包含共享 SQL 区和PL/SQL 区-经过完全语法分析或编译的PL/SQL 块和SQL 语句的表示法。PL/SQL 块包括:
• 过程和函数
• 程序包
• 触发器
• 匿名PL/SQL 块
数据字典高速缓存:数据字典高速缓存将字典对象的定义存放在内存中。
结果高速缓存:结果高速缓存包括 SQL 查询结果高速缓存和PL/SQL 函数结果高速缓存。此高速缓存用于存储SQL 查询或PL/SQL 函数的结果,以加快它们将来的执行速度。
用户全局区:UGA 包含 Oracle 共享服务器的会话信息。使用共享服务器会话时,如果尚未配置大型池,则UGA 位于共享池中。
大型池
• 为以下对象提供大型内存分配:
– 共享服务器和 Oracle XA 接口的会话内存
– I/O 服务器进程
– Oracle DB 备份和还原操作
– 并行查询操作
– 高级排队内存表存储
• 减少潜在的共享池碎片
• 是由AMM 和ASMM 管理的
• 大小是由LARGE_POOL_SIZE参数指定的
大型池
数据库管理员可以配置一个称为大型池的可选内存区,以便为以下对象提供大型内存分配:
• 共享服务器和Oracle XA 接口(在事务处理与多个数据库交互时使用)的会话内存
•I/O 服务器进程
• Recovery Manager (RMAN) I/O 从属进程的缓冲区
• 在语句并行执行中使用的消息缓冲区
• 高级排队内存表存储
通过为上面列项目分配会话内存,减少了共享池中由于频繁分配和取消分配大对象而产生的碎片。将大对象从共享池中分离出来,可增加共享池内存的使用效率,这意味着,它可以将更多内存用于处理新的请求,以及在需要时用于保留现有数据。
大型池可以由AMM 和ASMM 自动管理。还可以用 LARGE_POOL_SIZE参数设置其大小。
Java 池和流池
• Java 池内存用于将JVM 中特定于会话的所有Java 代码和数据存储在服务器内存中。
• Oracle Streams 专门使用流池内存来:
– 存储已缓冲的队列消息
– 为Oracle Streams 进程提供内存
Java 池和流池
Java 池内存用于将JVM 中特定于会话的所有 Java 代码和数据存储在服务器内存中。Java 池内存的使用方式有多种,具体取决于Oracle DB 运行的模式。
Java 池指导统计信息提供有关用于Java 的库高速缓存内存的信息,并且预测如何更改Java 池的大小就可以影响分析速率。将statistics_level 设置为TYPICAL或更高级别时,则在内部打开Java 池指导。关闭指导时,将重置这些统计信息。
流池专门由Oracle Streams 使用。流池存储已缓冲的队列消息,并且为Oracle Streams 捕获进程和应用进程提供内存。
除非专门配置流池,否则其大小以零开始。使用Oracle Streams 时,池大小会根据需要动态地增长。
重做日志缓冲区
• SGA 中的循环缓冲区
• 存放对数据库所做更改的信息
• 包含重做条目,重做条目中具有重做由诸如DML 和DDL 操作所做更改的信息
日志写进程(LGWR) 传送的内容:
– 用户进程提交事务处理时
– 重做日志缓冲区满三分之一时
– DBW n 进程将修改的缓冲区写入磁盘之前
Oracle Server 进程将重做条目从用户的内存空间复制到每个DML 或DDL 语句的重做日志缓冲区。重做条目包含重建或重做DML 和DDL 操作对数据库的更改所必需的信息。它们用于数据库恢复,需要占用缓冲区中的连续空间。
重做日志缓冲区是一个回收缓冲区;服务器进程可以用新条目覆盖重做日志缓冲区中已写入磁盘的条目。LGWR 进程的写速度通常都很快,足以确保缓冲区中始终有存储新条目的空间。LGWR 进程将重做日志缓冲区写入磁盘上的活动联机重做日志文件(或活动组成员)中。LGWR 进程将LGWR 上次写入磁盘以来进入缓冲区的所有重做条目复制到磁盘。
什么导致LGWR 执行写操作?
在以下情况下,LGWR 会从重做日志缓冲区中写出重做数据:
• 用户进程提交事务处理时
• 每隔三秒钟,或者重做日志缓冲区满三分之一时
• DBW n 进程将修改的缓冲区写入磁盘时(如果相应的重做日志数据尚未写入磁盘)
自动内存管理:概览
通过自动内存管理,数据库可以根据工作量自动调整SGA 和PGA 的大小。
ALTER SYSTEM SET MEMORY_TARGET=300M;
通过自动内存管理(AMM),Oracle DB 可以自动管理SGA 内存以及实例PGA 内存的大小。为此,在大多数平台上,只需要设置一个目标内存大小初始化参数( MEMORY_TARGET) 和一个最大内存大小初始化参数( MEMORY_MAX_TARGET),数据库就会根据处理需求在SGA 与实例 PGA 之间动态交换内存。
通过导航到“Server >Memory Advisors (服务器> 内存指导)”(在“Database Configuration(数据库配置)”区域中),并单击“Enable(启用)”按钮,可启用Oracle Enterprise Manager 中的AMM。

启用自动内存管理后, 数据库将会自动设置内存的最佳分配方式。将不时更改内存分配以适应工作量的变化。 “最大内存大小”指定数据库可以分配的,并且为了使用自动内存管理而必须设置的内存量。
通过这种内存管理方法,数据库还可以动态调整单个SGA 组件的大小以及单个PGA 的大小。
因为目标内存初始化参数是动态的,因此可以随时更改目标内存大小而不必重新启动数据库。最大内存大小相当于一个上限,以防你无意中将目标内存大小设置得太高。因为某些SGA 组件的大小不容易收缩,或者其大小必须不低于某个下限值,所以数据库还要防止你将目标内存大小设置得太低。
这种间接的内存转移依赖于操作系统(OS) 的共享内存释放机制。将内存释放给 OS 后,其它组件可以通过向OS 请求内存来分配内存。目前,Linux、Solaris 、HPUX、AIX 和Windows 平台上已实施了自动内存管理。

扫描二维码关注我的微学堂
搜索刘老师微信号:Rman-2014,备注“Oracle学习与咨询”,即可添加好友;或者扫描下面二维码,关注我的“微学堂”公众号,了解最新OCP认证动态、题库及答案解析、培训机构及讲师介绍、课堂授课内容等。每天还有一篇技术文章发布哦!





