ORACLE体系结构 - 内存(SGA、PGA)

ORACLE 内存结构示意图
内存结构示意图

一、系统全局区(SGA)

1. SGA 概述

SGA(System Global Area,系统全局区)是Oracle实例启动时分配的共享内存区域,贯穿实例整个生命周期(启动时分配,关闭时释放),用于存储数据库运行的关键信息(如数据块、SQL执行计划、重做日志条目等)。其核心特性可概括为:

  • 共享性:所有会话(服务器进程)共享SGA中的数据,避免重复存储,是高并发场景的基础。
  • 动态调整:支持通过参数动态调整大小(部分组件需重启生效),灵活适配负载变化。
  • 可监控性:通过Oracle内置视图(如V$SGAV$SGASTAT)实时监控使用状态,便于问题排查。

2. SGA 核心原理

  • 内存工作集:SGA是Oracle实例在内存中维护的数据库活动状态工作集,包含当前最活跃、最需快速访问的数据和控制信息。
  • LRU算法及变种:缓冲区(Buffer Cache、Shared Pool)的管理核心是最近最少使用(LRU)算法或其优化变种(如Touch Count、KEEP/RECYCLE池)。当需要空间缓存新内容时,优先淘汰最久未被访问或访问频率最低的条目。
  • 闩锁(Latch)与互斥体(Mutex):由于SGA是共享资源,多进程并发访问时需通过轻量级同步机制(Latch/Mutex)保护内部数据结构的完整性和一致性。获取Latch/Mutex的争用是性能调优的重要关注点。
  • 检查点(Checkpoint):DBWn进程根据检查点事件将脏缓冲区(已修改但未写入磁盘的数据块)写入数据文件,保证内存数据与磁盘文件在某一时间点的一致性,缩短实例恢复时间。
  • 日志先行(Write-Ahead Logging, WAL)
    • 核心原理:任何对数据块的修改产生前,必须先在重做日志缓冲区中生成对应的重做记录(Redo Record)。
    • LGWR写盘触发时机:事务提交前、缓冲区满1/3、每3秒、DBWn写脏块前等。
    • 作用:确保实例崩溃时,已提交事务的修改可通过重做日志恢复(前滚),未提交事务的修改可撤销(回滚),是实现事务ACID属性中持久性(Durability)的关键。

3. SGA 核心组件

(1)数据库缓冲区高速缓存(Database Buffer Cache / DB Cache)

核心作用:通过缓存数据文件中的数据块副本,最大化减少磁盘物理I/O,是SGA中通常占比最大、对性能影响最显著的组件。

  • 核心结构

    • 缓冲区(Buffers):与数据库块大小一致的内存块(如8KB),存储单个数据块副本。
    • 缓冲区头(Buffer Headers):记录缓冲区元数据(状态、访问时间、数据文件/块号映射等)。
    • 哈希桶(Hash Bucket / Cache Buffers Chains):通过<file#, block#>哈希定位数据块,访问需获取Cache Buffers Chains Latch
    • LRU/LRUW链表:管理缓冲区淘汰顺序,LRU链存储可重用的干净缓冲区,LRUW链存储待写入磁盘的脏缓冲区。
  • 缓冲区状态

    • 脏(Dirty):内容已修改且未写盘,需由DBWn进程异步写入数据文件。
    • 干净(Clean):内容与磁盘数据一致,可被重用。
    • 空闲(Free):为空,可直接缓存新数据块。
    • Pin状态:被进程锁定访问,防止被淘汰或覆盖。
  • 工作机制

    • 读操作:优先检查缓存(逻辑读),未命中则触发物理读,将磁盘块加载到空闲缓冲区。
    • 写操作:先修改缓存中的数据块(标记为脏),由DBWn进程根据触发条件(如脏块数量、检查点)异步写回磁盘。
  • 优化要点

    • 多缓冲池配置:通过DB_KEEP_CACHE_SIZE(保留高频访问块)、DB_RECYCLE_CACHE_SIZE(临时存储大扫描块)、DB_nK_CACHE_SIZE(非默认块大小)分离不同访问模式的对象。
    • 命中率监控:通过V$BUFFER_POOL_STATISTICS计算命中率(目标>95% for OLTP),公式:(1 - PHYSICAL_READS/(DB_BLOCK_GETS + CONSISTENT_GETS)) * 100
    • 避免过度分配:过大缓冲区会降低LRU扫描效率,增加CPU开销。
(2)重做日志缓冲区(Redo Log Buffer)

核心作用:临时存储事务产生的重做条目(Redo Entries),记录数据修改细节,是保障数据持久性和崩溃恢复的关键组件。

  • 核心结构:环形缓冲区(Circular Buffer),循环存储重做条目。

  • 工作机制

    • 服务器进程生成重做条目后,先写入重做日志缓冲区。
    • LGWR进程负责将缓冲区内容写入在线重做日志文件,触发条件包括:
      • 事务提交(COMMIT);
      • 缓冲区使用率达1/3;
      • 每3秒定时触发;
      • DBWn写脏块前(遵循WAL协议:先写日志后写数据)。
  • 优化要点

    • 避免等待事件log buffer space等待表明缓冲区不足,需调整LOG_BUFFER参数(通常16MB-64MB)。
    • 减少小事务提交:频繁小提交会增加LGWR写入压力,建议批量提交。
    • 监控指标:通过V$SYSTEM_EVENT监控log buffer space等待次数(应接近0)。
(3)共享池(Shared Pool)

核心作用:缓存可共享的SQL/PLSQL代码、执行计划及数据字典元数据,减少重复解析开销,是OLTP系统性能核心。

  • 核心子组件

    • 库高速缓存(Library Cache)

      • 存储SQL解析树、执行计划、PLSQL代码(过程/函数/包)。
      • 关键机制:通过LRU算法管理缓存,区分软解析(复用执行计划)和硬解析(重新生成计划)。
      • 优化关键:使用绑定变量(如:var)提高游标共享性,减少硬解析(硬解析消耗大量CPU和Latch)。
    • 数据字典高速缓存(Dictionary Cache / Row Cache)

      • 缓存表结构、权限、约束等元数据(如tab$col$系统表信息)。
      • 作用:减少解析SQL时对系统表空间的物理读,命中率应>90%(通过V$ROWCACHE监控)。
  • 优化要点

    • 参数配置SHARED_POOL_SIZE(OLTP建议占SGA的20%-30%)、SHARED_POOL_RESERVED_SIZE(预留5%-10%用于大SQL)。
    • 监控指标V$LIBRARYCACHEGETHITRATIO(目标>95%)、RELOADS(硬解析次数,应最小化)。
    • 避免游标失效:减少频繁DDL操作(会导致依赖游标失效)。
(4)大池(Large Pool)(可选)

核心作用:为大内存消耗操作提供专用内存,避免共享池碎片化,提升内存分配效率。

  • 典型使用场景

    • RMAN备份/恢复的I/O缓冲区;
    • 共享服务器模式下的UGA(用户全局区);
    • 并行查询(PX进程)的消息传递;
    • I/O从属进程的缓冲区。
  • 优化要点

    • 参数配置:通过LARGE_POOL_SIZE设置(默认0,RMAN场景建议64MB-256MB)。
    • 必要性:若使用上述场景而未配置大池,Oracle会从共享池“偷取”内存,导致共享池不足。
(5)Java池(Java Pool)(可选)

核心作用:为数据库内嵌JVM提供内存,支持Java存储过程、SQLJ程序等Java相关功能。

  • 优化要点
    • 参数配置JAVA_POOL_SIZE(不使用Java功能时保持默认16MB,使用时建议64MB-256MB)。
    • 适用场景:仅当应用涉及Java存储过程时需要关注,否则无需额外分配。
(6)流池(Streams Pool)(已弃用)

核心作用:为Oracle Streams(数据捕获与传播技术)提供内存,缓存变更数据和队列消息。

  • 优化要点
    • 参数配置STREAMS_POOL_SIZE(默认0,使用Streams时建议64MB-512MB)。
    • 注意事项:12c后Streams逐步被GoldenGate替代,未使用时可忽略。
(7)固定SGA(Fixed SGA)

核心作用:SGA的“元数据区”,存储指向SGA其他组件的指针、进程通信状态、实例级原子变量(如SCN)等。

  • 特点:大小由Oracle内部决定(通常几百KB到几MB),DBA无法直接配置,贯穿实例生命周期。
(8)IM列存储(In-Memory Column Store)(可选)

核心作用:以“列格式”在内存中存储指定表/分区的数据,独立于传统行式缓存(Database Buffer Cache),支持列压缩、向量计算(SIMD指令),高效支撑混合负载(交易+分析)。

  • 核心结构

    • 列存储单元:按列聚合存储数据,支持列式压缩(如压缩级别INMEMORY COMPRESS FOR QUERY LOW/HIGH)。
    • 内存区域:通过INMEMORY_SIZE参数指定大小(需在SGA_MAX_SIZE范围内),属于SGA的独立区域。
  • 工作机制

    • 需通过ALTER TABLE ... INMEMORY或表空间级DEFAULT INMEMORY显式启用。
    • 数据加载:支持自动加载(首次访问时)或强制加载(PRIORITY子句),加载后常驻内存直至实例关闭或手动卸载。
    • 查询优化:分析类查询直接扫描列存储(避免行式缓存的冗余数据读取),通过向量计算加速聚合、过滤操作。
  • 优化要点

    • 适用场景:优先为分析高频、变更低频的表(如历史订单表、报表基表)启用,避免频繁更新的表(会增加内存刷新开销)。
    • 参数配置INMEMORY_SIZE(建议占SGA的10%-30%,根据分析负载调整)、INMEMORY_AUTOMATIC_LEVEL(自动管理列存储优先级,12cR2+)。

4. SGA 调优最佳实践

  • 基于业务负载的内存分配建议

    • OLTP系统(高并发小事务):缓冲区缓存(50%-60%)> 共享池(20%-30%)> 其他组件(10%-20%)。
    • OLAP系统(大查询、报表):缓冲区缓存(40%-50%)+ In-Memory列存储(若启用,10%-30%)> 共享池(15%-20%)。
  • 关键监控视图

    视图名 用途 核心指标
    V$SGA / V$SGAINFO SGA总览与组件大小 总大小、各组件占比、粒度(Granule)
    V$SGASTAT 组件详细使用量(已用/空闲内存) 共享池保留内存、缓冲区空闲比例
    V$LIBRARYCACHE 库缓存性能 命中率(GETHITRATIO)、RELOADS
    V$BUFFER_POOL_STATISTICS 缓冲区缓存性能 物理读、逻辑读、命中率
    V$INMEMORY_AREA IM列存储使用状态 已用/空闲空间、压缩率
  • 避免常见误区

    • 过度分配SGA:超过物理内存会导致操作系统Swap,反而降低性能(建议SGA占物理内存的50%-70%)。
    • 忽略SGA_MAX_SIZE:若SGA_TARGET动态调整时超过SGA_MAX_SIZE,会触发ORA-04031错误。
    • 忽视自动管理的局限性:ASMM可能对特殊负载(如超大SQL)适配不佳,需结合手动配置SHARED_POOL_RESERVED_SIZE等参数。

二、程序全局区(PGA)

1. PGA 概述

PGA(Program Global Area,程序全局区)是每个服务器进程专属的非共享内存区域,随进程创建而分配、随进程终止而释放,用于存储会话私有信息和内存密集型操作的临时工作数据。其核心特性可概括为:

  • 私有性:仅归属单个服务器进程,不与其他进程共享,避免共享资源的并发争用(如Latch竞争)。
  • 会话绑定:每个会话(无论专用服务器还是共享服务器模式)均关联一个PGA,存储会话专属的状态和操作数据。
  • 动态伸缩:在自动管理模式下,内存大小随会话负载(如排序数据量、哈希连接规模)动态调整。
  • 功能聚焦:专为会话私有操作(如排序、哈希连接)设计,与SGA的共享功能形成互补。

2. PGA 核心原理

  • 内存独占性:PGA由操作系统为进程单独分配,仅该进程可访问;进程结束后,PGA由操作系统自动回收,无需Oracle手动管理。

  • 工作区管理机制:内存密集型操作的效率取决于工作区内存是否充足,分为三种执行模式:

    • 理想执行(Optimal Execution):工作区内存完全满足操作需求,全程在内存中完成,性能最佳。
    • 单遍执行(One-pass Execution):内存不足,需将部分中间数据写入临时表空间,额外一次磁盘读写,性能下降约50%。
    • 多遍执行(Multi-pass Execution):内存严重不足,需多次读写临时表空间,性能急剧恶化(较理想执行慢10倍以上),应绝对避免。
    • 算法目标:Oracle优化器根据PGA_AGGREGATE_TARGET和操作数据量估算,优先保障操作在Optimal或One-pass模式下运行。
  • 自动内存管理(APMM)

    • 从Oracle 9i开始,通过PGA_AGGREGATE_TARGET参数实现自动管理,替代手动配置SORT_AREA_SIZE等参数。
    • 核心机制:后台进程(MMAN)监控所有会话的工作区使用,动态分配内存——为活跃的大操作优先分配内存,回收非活跃操作的闲置内存,最大化Optimal执行比例。

3. PGA 核心组件(以专用服务器模式为主)

(1)私有SQL区域(Private SQL Area)

核心作用:存储会话执行SQL的私有状态信息,包括绑定变量值和游标运行时数据,是会话与SQL执行的“桥梁”。

  • 核心结构

    • 绑定变量区:存储当前执行中使用的绑定变量具体值(如:id=100中的“100”)。
    • 游标状态区:记录游标生命周期状态(打开、解析、执行、获取)及当前行指针位置。
    • 运行时数据区:存储SQL执行中的临时计算结果(如复杂表达式中间值、函数调用返回值)。
  • 工作机制

    • 会话解析SQL时,Oracle在PGA中为该SQL创建私有SQL区域,与SGA库缓存中的共享SQL区域(存储执行计划)关联。
    • 游标关闭后,私有SQL区域可被SESSION_CACHED_CURSORS参数缓存,避免重复创建(减少软软解析开销)。
  • 优化要点

    • 合理设置SESSION_CACHED_CURSORS(建议50-200),缓存高频使用的关闭游标,减少重建私有SQL区域的开销。
    • 避免会话长期持有大量打开的游标(通过OPEN_CURSORS限制,默认500),防止PGA内存泄漏。
(2)SQL工作区(SQL Work Areas)

核心作用:为内存密集型操作提供临时工作空间,是PGA中占比最大、对性能影响最直接的组件。

  • 核心类型与适用场景

    • 排序区(Sort Area):支持ORDER BYGROUP BYDISTINCT、索引创建、UNION等排序操作。
    • 哈希区(Hash Area):用于哈希连接(HASH JOIN)和哈希聚合(GROUP BY使用HASH GROUP BY时),存储哈希表。
    • 位图合并区(Bitmap Merge Area):合并多个位图索引扫描结果(BITMAP MERGE)。
    • 批量装载区(Write Buffers):缓存直接路径插入(INSERT /*+ APPEND */)、并行DML的临时写入数据。
  • 工作机制

    • 操作启动时,Oracle根据数据量和PGA_AGGREGATE_TARGET自动分配工作区内存(不超过隐含参数_PGA_MAX_SIZE限制,默认200MB)。
    • 内存不足时,自动将溢出数据写入临时表空间(以“临时段”形式存储),操作完成后释放临时段。
  • 优化要点

    • 监控V$SQL_WORKAREA_ACTIVE,识别长期处于ONEPASSMULTIPASS模式的操作,优先为其分配更多内存。
    • 对超大排序/哈希操作(如全表排序),可通过/*+ PGA_AGGREGATE_TARGET(n) */hint临时调整会话级PGA目标(需谨慎使用)。
(3)会话内存(Session Memory)

核心作用:存储会话的固定状态信息和控制结构,是会话标识和运行环境的“基石”。

  • 核心内容

    • 登录信息:用户名、权限集、角色激活状态、会话ID。
    • 环境配置:NLS参数(NLS_LANGUAGENLS_DATE_FORMAT)、优化器参数(OPTIMIZER_MODEHASH_JOIN_ENABLED)。
    • 控制结构:会话堆栈空间(PL/SQL调用栈、递归SQL执行栈)、打开的数据库链接信息。
  • 特点

    • 大小相对固定(通常几KB到几十KB),不受工作负载波动影响。
    • 在共享服务器模式下,会话内存(UGA)迁移至SGA的大池,便于多个共享服务器进程访问。
(4)游标区(Cursor Area)

核心作用:管理会话中显式或隐式打开的游标,记录游标属性和执行状态,是私有SQL区域的“管理单元”。

  • 核心内容

    • 游标属性:SQL文本、解析状态、绑定变量类型、fetch方向(正向/反向)。
    • 执行统计:已获取行数、影响行数、错误码(若执行失败)。
  • 与私有SQL区域的关系:一个游标对应一个私有SQL区域,游标区负责管理游标生命周期(打开-执行-获取-关闭),私有SQL区域存储具体执行数据。

4. PGA 调优最佳实践

  • 基于业务负载的内存分配建议

    • OLTP系统(小事务、少排序):PGA占总内存的10%-20%,PGA_AGGREGATE_TARGET = 活跃会话数 × 5MB(单会话平均PGA)。
    • DSS/数据仓库(大查询、多排序/哈希):PGA占总内存的30%-50%,PGA_AGGREGATE_TARGET = 活跃会话数 × (50MB-200MB)(单会话平均PGA)。
  • 关键监控视图

    视图名 用途 核心指标
    V$PROCESS 进程级PGA使用监控 PGA_USED_MEM(已用)、PGA_MAX_MEM(历史峰值)
    V$SESSTAT + V$STATNAME 会话级统计 session pga memory(当前使用)、sorts (disk)(磁盘排序次数)
    V$PGASTAT(核心) PGA整体状态摘要 cache hit percentage(内存命中率,目标>90%)、over allocation count(超分次数,目标0)
    V$SQL_WORKAREA 工作区详细使用情况 操作类型、执行模式(Optimal/Onepass/Multipass)、内存使用量
    V$TEMPSEG_USAGE 临时表空间使用监控 占用空间、关联会话/SQL、操作类型(排序/哈希)
  • 优化方向

    • 合理设置PGA_AGGREGATE_TARGET:通过V$PGA_TARGET_ADVICE视图预测不同目标值的性能影响(选择命中率>90%的最小值)。
    • 优化高PGA消耗SQL
      • 重写SQL减少数据量(如增加过滤条件),避免全表排序/哈希连接;
      • 创建索引替代排序(如ORDER BY字段建索引),或改用嵌套循环连接(小驱动集场景);
    • 优化临时表空间:使用TEMPFILE(而非数据文件),放置于SSD等高性能存储;采用临时表空间组(TEMPORARY TABLESPACE GROUP)分散I/O压力。
    • 控制会话并发:DSS系统中限制大查询并发数(如通过资源管理器),避免PGA内存竞争。

三、Oracle 内存管理

1. 核心管理模式

Oracle内存管理围绕SGA和PGA的分配与调整展开,主要有三种模式:

(1)自动内存管理(AMM - Automatic Memory Management)
  • 原理:通过MEMORY_TARGET参数统一管理SGA和PGA,Oracle自动分配两者比例及内部组件大小,无需手动配置。

  • 核心参数

    参数名 作用 说明
    MEMORY_TARGET 动态调整的总内存大小(SGA+PGA) 需≤MEMORY_MAX_TARGET
    MEMORY_MAX_TARGET 实例可使用的最大内存上限 静态参数(需重启生效)
  • 适用场景与局限性

    • 适用:中小规模数据库、运维资源有限的环境(简化管理)。
    • 局限性:对内存调整的粒度和时机控制较弱,高并发场景可能出现调整延迟,逐渐被ASMM替代。
(2)自动共享内存管理(ASMM - Automatic Shared Memory Management)
  • 原理:设置SGA_TARGET参数,Oracle自动调整SGA内部组件(共享池、缓冲区缓存等)的大小;PGA通过PGA_AGGREGATE_TARGET自动管理(APMM),兼顾灵活性与可控性。

  • 核心参数

    参数名 作用 约束条件
    SGA_TARGET SGA的动态调整总大小 需≤SGA_MAX_SIZE
    SGA_MAX_SIZE SGA的最大上限(静态参数,需重启) 默认等于SGA_TARGET,建议设为预期最大值
    SGA_MIN_SIZE SGA的最小保障值(19c新增) 确保内存紧张时SGA不低于此值(默认0)
    PGA_AGGREGATE_TARGET PGA总目标大小(动态调整) 控制工作区内存分配
  • 适用场景与优势

    • 适用:中大型数据库、需要控制SGA与PGA比例的场景(如OLTP)。
    • 优势:可根据实时工作负载优化内存利用,减少人工干预,是主流推荐模式。
(3)手动共享内存管理(MSMM - Manual Shared Memory Management)
  • 原理:不设置SGA_TARGET,手动指定SGA各组件大小(如SHARED_POOL_SIZEDB_CACHE_SIZE),总和需≤SGA_MAX_SIZE;PGA需手动设置*_AREA_SIZE参数(如SORT_AREA_SIZE)。
  • 适用场景与劣势
    • 适用:核心生产库、有明确性能需求的场景(如高并发OLTP)。
    • 劣势:需频繁人工调整以适应负载变化,易导致内存浪费或不足。

2. 管理模式对比与选择

管理方式 核心特点 适用场景 推荐度
AMM 全自动化,仅需配置总内存 中小库、运维简单场景 ⭐⭐⭐
ASMM 自动调整SGA内部组件和PGA,灵活可控 中大型库、多数生产环境 ⭐⭐⭐⭐⭐
MSMM 手动配置各组件,精细控制 核心库、极端定制场景 ⭐⭐

3. 内存管理最佳实践

  • 合理规划SGA与PGA规模:通常SGA占系统内存的50%-70%,PGA占20%-30%(预留10%-20%给操作系统)。
  • 善用内存顾问工具:通过V$SGA_TARGET_ADVICE(SGA)和V$PGA_TARGET_ADVICE(PGA)获取配置建议,避免经验主义偏差。
  • 优化内存利用效率:如调整缓冲区缓存减少磁盘读、优化共享池减少硬解析、控制PGA工作区避免磁盘排序。
  • 控制总内存需求:避免过度分配导致系统swap(内存交换),通过vmstattop监控swap使用(理想为0),引发性能骤降。

内存管理架构示意图

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐