Oracle 内存结构
- 系统全局区 (SGA):由所有服务器进程和后台进程共享
- 数据库缓冲区高速缓存:用于缓存从磁盘检索到的数据块
- 重做日志缓冲区:用于缓存重做信息,直到其可以写入磁盘为止
- 共享池:用于缓存可在用户间共享的各种结构
- 大型池:用于缓冲大型I/O 请求的可选区域
- Java 池:用于存放Java 虚拟机(JVM) 中特定于会话的Java 代码和数据
- 流池:由 Oracle Streams 使用
- 保留缓冲区高速缓存:用于存放会尽可能长地保留在缓冲区高速缓存中的数据
- 循环缓冲区高速缓存:用于存放缓冲区高速缓存中很快过期的数据
- nK 块大小缓冲区高速缓存:用于缓存大小与默认数据库块大小不同的数据块,用来支持可传输的表空间
- 程序全局区 (PGA):由每个服务器和后台进程专用,每个进程都有一个PGA。
- 专用 SQL 区:包含绑定信息和运行时内存结构等数据。发出 SQL 语句的每个会话都有一个专用 SQL 区。
- 会话内存:此处分配的内存用于存放会话变量以及与该会话相关的其它信息
- 缓冲区高速缓存
- 通过指定 DB_CACHE_SIZE 参数的值,可以配置缓冲区高速缓存。
- 缓冲区高速缓存可存放数据文件中块大小为 DB_BLOCK_SIZE 的数据块的副本。(其有效值介于 2K 和 32K 之间,默认值为 8K)
- 在任何给定时间,缓冲区高速缓存都可能会存放一个数据库块的多个副本。虽然该块只存在一个当前副本,但为了满足查询需要,服务器进程可能需要根据过去的映像信息构造读一致性副本。这称为读一致性 (CR) 块。
- 最近最少使用 (LRU) 列表可监视缓冲区的使用情况。
- 四种状态
-
- 已连接:当前正将该块读入高速缓存或正在写入该块。其它会话正等待访问该块。
- 干净的:该缓冲区目前未连接,如果其当前内容(数据块)将不再引用,则可以立即执行过期处理。这些内容与磁盘保持同步,或者缓冲区包含块的读一致性快照。
- 空闲/未使用:缓冲区因实例刚启动而处于空白状态。此状态与“干净的”状态非常相似,不同之处在于缓冲区未曾使用过。
- 灰:缓冲区不再处于连接状态,但内容(数据块)已更改,因此必须先通过 DBWn将内容刷新到磁盘,然后才能执行过期处理。
- 使用多个缓冲区池
-
- 保留:此池用于保留内存中可能要重用的对象
- 循环:此池用于内存中重用几率很小的块。循环池的大小要小于分配给该池的各个段的总大小。
- 默认:此池始终存在。它相当于没有保留池和循环池的实例的缓冲区高速缓存,可通过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); - 共享池
- 大小通过 SHARED_POOL_SIZE 指定
- 库高速缓存包含语句文本、已进行语法分析的代码和执行计划。
- 数据字典高速缓存包含数据字典表中各表、列和权限的定义
- 用户全局区 (UGA) 包含会话信息(如果使用 Oracle 共享服务器)
- 大型池
- 可配置为 SGA 中一个单独的内存区
- 大小由 LARGE_POOL_SIZE 参数指定
- 用于在内存中为以下各项存储数据
- UGA
- 备份和还原操作
- 并行查询消息传送
- Java 池
- 可配置为 SGA 中一个单独的内存区
- 大小由 JAVA_POOL_SIZE 参数指定
- 用于将 JVM 中特定于会话的所有 Java 代码和数据存储在内存中
- 重做日志缓冲区
- Oracle 服务器进程将重做条目从用户的内存空间复制到每个 DML 或 DDL 语句的重做日志缓冲区。重做条目包含重建或重做 DML 和 DDL 操作对数据库的更改所必需的信息。它们用于数据库恢复,需要占用缓冲区中的连续空间。
- LGWR 会从重做日志缓冲区中写出重做数据的情况
-
- 用户进程提交事务处理时
- 每隔三秒钟,或重做日志缓冲区三分之一的空间已填满,或包含至少 1 MB 数据时
- DBWn进程将修改的缓冲区写入磁盘时(如果相应的重做日志数据尚未写入磁盘)
自动管理共享内存
- 概览
- 自动根据工作量变化调整
- 最大程度地提高内存利用率
- 有助于消除内存不足的错误
- SGA 大小初始化参数(SGA_TARGET) 包含 SGA 中的所有内存,其中包括自动调整大小的组件、手动调整大小的组件以及启动期间的所有内部分配
- 工作原理
- ASMM 以 MMAN 在后台捕获的工作量信息为基础
- MMAN 使用内存指导
- 将内存移到最迫切需要的地方
- 如果使用 SPFILE(推荐)
- 在关闭时保存组件大小
- 保存的值用于引导程序组件大小
- 无需再确定最佳值
- 配置ASMM
- EM
- 管理--->内存参数--->SGA选项卡--->enable
- 手动
- 要使某些内存组件具有最小大小,应手动配置这些组件大小
- 如果自动计算得出的大小因某种原因不能满足您的需要
- 如果所需内存中存在 ASMM 未检测到的短期峰值或谷值
- 如果只想确保特定组件的最小内存量
- 设置sga_target,将STATISTICS_LEVEL 设置为 TYPICAL 或 ALL
- 自动优化的 SGA 参数的行为
- 未设置 SGA_TARGET 或将其设置为零时
- 自动优化的参数行为正常
- SHARED_POOL_SIZE 可能需要根据早期数据库版本中使用的设置增加
-
SELECT SUM(bytes)/1024/1024 size_mb
FROM v$sgastat WHERE pool = 'shared pool'; - SGA_TARGET 设置为非零值时
- 自动优化的参数的默认值为零
- 指定的值用作下限大小
-
SELECT component, current_size/1024/1024 size_mb
FROM v$sga_dynamic_components; - 不能自动优化(必须使用数据库参数手动配置,会减少可用于自动优化 SGA 的内存量)
- KEEP(保留)和 RECYCLE(循环)缓冲区高速缓存
- 具备多个块大小的高速缓存
- 使用 V$PARAMETER 视图 查看参数
- 修改 SGA_TARGET 参数(只会影响自动调整大小的组件)
- 是动态参数
- 最多可增大到 SGA_MAX_SIZE
- 可以减小,直到所有组件都达到其下限大小为止
- 禁用 ASMM
- 将 SGA_TARGET 设置为零可禁用自动优化功能
- 自动优化的参数设置为其当前大小
- SGA 大小总体上不受影响
- 手动调整动态 SGA 参数的大小(只会影响 SGA 的可调部分)
- 导致组件大小立即调整(如果新值大于当前值)
- 更改下限大小(如果新值小于当前大小)
程序全局区 (PGA)
- 自动 PGA 内存管理
- 根据 PGA_AGGREGATE_TARGET 参数,动态调整专用于工作区的 PGA 内存量
- 有助于最大限度地提高所有内存密集型 SQL 操作的性能
- 默认情况下是启用的
- PGA 管理资源
- 管理 PGA_AGGREGATE_TARGET 初始化参数的统计信息,如 PGA 高速缓存命中百分比
- 用于监视 PGA 工作区的视图包括:
-
- v$sql_workarea_histogram
- v$pgastat
- v$sql_workarea_active
- v$sql_workarea
- v$tempseg_usage
- 用于调整 PGA 工作区大小的视图有:
-
- v$pga_target_advice
- v$pga_target_advice_histogram
有效使用内存准则
- 尽量使 SGA 适合物理内存
- 优化以实现高缓冲区高速缓存命中率,但要注意以下几点:
-
- 即使有效且必需的全表扫描也会降低命中率
- 可能存在因不必要地重复读取同一块而出现命中率虚升的情况。
- 使用内存指导
库高速缓存的内存优化准则
- 为开发人员制定格式使用约定,以便 SQL 语句符合高速缓存的要求。
- 使用绑定变量
- 消除不必要的重复 SQL
- 考虑使用 CURSOR_SHARING
- 尽可能使用 PL/SQL
- 缓存序列号
- 连接库高速缓存中的对象