目 录CONTENT

文章目录

Oracle体系结构-PGA详解

暮渔木鱼
2025-08-01 / 0 评论 / 0 点赞 / 0 阅读 / 0 字 / 正在检测是否收录...

一、 PGA 的设计目标与核心思想

  1. 私有 (Private):
    • 核心设计理念: PGA 是每个服务器进程(Server Process)专属的、非共享的内存区域。每个连接到数据库的会话(无论是专用服务器 Dedicated Server 还是共享服务器 Shared Server)都关联一个 PGA。
    • 解决的问题: 存储与会话强相关无需共享的信息,避免在共享内存(SGA)中引入不必要的同步开销(如 Latch)和复杂性。提供会话的独立工作空间。
  2. 会话上下文 (Session Context):
    • 存储会话特有的状态信息和控制数据,如登录信息、会话变量(NLS 设置)、游标状态、堆栈空间等。
  3. 工作区 (Work Area):
    • 为 SQL 语句执行过程中需要大量内存的操作提供临时工作内存。这是 PGA 最重要的功能之一,直接影响执行效率。
    • 主要操作类型:
      • 排序 (ORDER BY, GROUP BY, DISTINCT, 索引创建, UNION 等)
      • 哈希连接 (HASH JOIN)
      • 位图合并 (BITMAP MERGE)
      • 位图创建 (BITMAP CREATE)
      • 批量装载 (WRITE BUFFERS 用于直接路径插入等)
    • 解决的问题: 这些操作需要中间结果集。如果能在内存中完成,速度极快;如果内存不足被迫使用磁盘(临时表空间),性能会急剧下降。
  4. 数据缓冲 (Data Buffering - 可选):
    • 专用服务器模式 (Dedicated Server) 下,PGA 通常包含一个私有 SQL 区域 (Private SQL Area),用于存储绑定变量值、查询执行状态信息、以及运行时内存
    • 共享服务器模式 (Shared Server / MTS) 下,会话的用户全局区 (UGA) - 包含私有 SQL 区域和会话状态 - 通常位于 SGA 的大池 (Large Pool) 中(为了在调度进程间共享),而不是在 PGA 中。此时 PGA 主要服务于共享服务器进程本身的后台数据结构。
  5. 高效执行: 通过为每个进程提供独立的私有空间,避免了并发访问共享资源的争用,简化了内存管理,提高了特定操作的执行效率。

二、 PGA 的核心原理

  1. 内存独占性: PGA 内存由操作系统进程分配,仅对该进程可见和可访问。进程结束时,PGA 被操作系统回收。
  2. 工作区管理:
    • 理想操作 (Optimal Execution): SQL 操作所需的内存完全在 PGA 工作区内分配。操作完全在内存中完成,性能最佳。
    • 单遍操作 (One-pass Execution): 工作区内存不足容纳整个操作,需要将部分中间数据写入磁盘上的临时表空间,并进行一次额外的读写操作。性能显著下降。
    • 多遍操作 (Multi-pass Execution): 工作区严重不足,需要多次读写磁盘上的临时数据。性能急剧恶化,应尽量避免。
    • 算法目标: Oracle 优化器根据可用的 PGA 内存和操作的数据量估算,尽量使操作在 OPTIMALONE-PASS 模式下运行。
  3. 自动内存管理: 从 Oracle 9i 开始引入 PGA_AGGREGATE_TARGET 参数,实现了 PGA 的自动管理 (Automatic PGA Memory Management - APMM)
    • DBA 设置一个实例级的总 PGA 目标大小。
    • Oracle 的 *_AREA_SIZE 参数(如 SORT_AREA_SIZE, HASH_AREA_SIZE)将被忽略(除非设置为最小值限制)。
    • 后台进程 MMAN (Memory Manager)MMON (Manageability Monitor) 负责监控所有工作区的内存使用。
    • 基于一个复杂的内部算法,Oracle 在所有活动工作区之间动态分配 PGA 内存
      • 优先保证活跃的、对性能影响大的操作(如正在执行的排序/哈希连接)获得足够内存以达到 OPTIMAL 模式。
      • 对于非活跃或低优先级的工作区,可能会回收其内存。
      • 目标是最大化 OPTIMAL 执行的比例,最小化磁盘 I/O (写入 TEMP 表空间)。
    • 优点: 极大简化管理,优化整体性能,适应变化的工作负载。

三、 PGA 的主要组件详解 (Dedicated Server 模式为主)

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

    • 位置: 每个会话在其 PGA 中都有自己的私有 SQL 区域。
    • 功能: 存储特定 SQL 语句执行状态运行时内存
    • 关键内容:
      • 绑定变量值 (Bind Variables): 当前执行使用的具体值。
      • 游标状态 (Cursor State): 游标是打开、解析、执行还是获取状态?当前行指针位置。
      • 运行时内存 (Runtime Memory): 处理 WHERE 子句中的复杂表达式、函数调用等所需的临时空间。
      • 查询执行工作区 (Query Execution Work Areas): 指向实际执行排序、哈希连接等操作所需的工作区的指针(工作区本身是 PGA 的另一部分)。
    • 生命周期: 通常与会话或游标的生命周期相关。当游标关闭或会话结束时释放。SESSION_CACHED_CURSORS 参数控制会话可以缓存的已关闭游标的私有 SQL 区域数量,以减少软软解析开销。
    • 注意:共享 SQL 区域 (Shared SQL Area) 区别:共享 SQL 区域位于 SGA 的库缓存中,存储的是 SQL 文本、解析树、执行计划等可共享的信息。私有 SQL 区域存储的是特定于会话的执行状态和变量值
  2. SQL 工作区 (SQL Work Areas):

    • 功能: 这是 PGA 中最重要、最消耗资源的部分,专门用于执行内存密集型操作
    • 主要类型:
      • 排序区 (Sort Area): 用于 ORDER BY, GROUP BY, DISTINCT, 索引创建, 集合操作 (UNION, INTERSECT, MINUS) 等排序操作。
      • 哈希区 (Hash Area): 用于哈希连接 (HASH JOIN) 和哈希聚合 (GROUP BY 使用 HASH GROUP BY 时)。存储哈希表。
      • 位图合并区 (Bitmap Merge Area): 用于合并多个位图索引扫描结果 (BITMAP MERGE)。
      • 位图创建区 (Bitmap Create Area): 用于创建位图索引时 (BITMAP CREATE)。
      • 批量装载区 (Write Buffers): 用于直接路径插入 (INSERT /*+ APPEND */)、并行 DML、外部表访问等操作的缓冲区。
    • 管理: 如前所述,在 APMM (PGA_AGGREGATE_TARGET) 下,由 Oracle 自动动态分配和管理大小。操作完成后,工作区内存被释放回 PGA 池。
  3. 会话内存 (Session Memory):

    • 功能: 存储会话的固定信息控制结构
    • 内容:
      • 会话登录信息 (用户身份、权限)。
      • 会话设置 (NLS_LANGUAGE, NLS_TERRITORY, OPTIMIZER_MODE 等)。
      • 打开数据库链接的信息。
      • 会话堆栈空间 (用于 PL/SQL 调用栈、递归 SQL 等)。
      • 会话相关的控制块和状态信息。
  4. 游标区 (Cursor Area - 可视为私有 SQL 区域的一部分):

    • 存储显式或隐式打开的游标的状态信息。

四、 PGA 的内存管理

  1. 管理模式:

    • 手动管理 (Manual PGA Management - 9i 之前):
      • 通过设置 *_AREA_SIZE 参数(如 SORT_AREA_SIZE, HASH_AREA_SIZE, BITMAP_MERGE_AREA_SIZE, CREATE_BITMAP_AREA_SIZE为每个操作指定固定大小的最大工作区
      • 缺点:
        • 难以设置:设置太小导致大量磁盘 I/O (ONE-PASS/MULTI-PASS),设置太大浪费内存且可能导致 ORA-4030 (PGA 内存不足) 或操作系统交换。
        • 不灵活:无法根据系统负载动态调整。
        • 不公平:一个消耗大量内存的操作可能独占资源,饿死其他操作。
      • 遗留参数: 在 APMM 下,这些参数通常被忽略,除非用作 _AREA_SIZE 参数的最小值下限(如果设置)。
    • 自动 PGA 管理 (APMM - 9i 及以后):
      • 设置 PGA_AGGREGATE_TARGET 参数。这是实例级的总目标。
      • Oracle 自动管理所有工作区的内存分配。
      • 强烈推荐使用! 是主流和最佳实践。
    • 自动内存管理 (AMM - 11g 及以后):
      • 设置 MEMORY_TARGET 参数。
      • Oracle 自动在 SGA (SGA_TARGET) 和 PGA (PGA_AGGREGATE_TARGET) 之间动态分配总内存。
      • 在 PGA 内部,仍然使用 APMM 机制管理各个工作区。
      • 简化整体内存管理。
  2. PGA_AGGREGATE_TARGET 的设置:

    • 初始估算: 一个常用的经验法则是:
      • 对于 OLTP 系统:PGA_AGGREGATE_TARGET = (总物理内存 * 20%) / 活跃并发进程数估算值
      • 对于 DSS/数据仓库系统:PGA_AGGREGATE_TARGET = (总物理内存 * 50% - 70%) / 活跃并发进程数估算值
      • 注意:这仅是起点,需要根据实际监控调整。必须给操作系统和 SGA 留足内存。
    • 动态调整: ALTER SYSTEM SET PGA_AGGREGATE_TARGET = nG [SCOPE=MEMORY|SPFILE|BOTH]; 可以在线调整(SCOPE=MEMORY 立即生效但不持久;SCOPE=SPFILE/BOTH 需重启生效或持久化)。
    • 最大值限制: 单个工作区能获得的最大内存由隐含参数 _PGA_MAX_SIZE 控制(通常默认为 200MB),即使 PGA_AGGREGATE_TARGET 设置很大。这是为了防止单个操作耗尽所有 PGA 资源。在极端 DSS 环境可能需要调整(谨慎!)。
  3. 共享服务器模式 (Shared Server / MTS) 的特殊性:

    • 在共享服务器模式下,服务器进程 (Shared Server Processes) 是池化的,服务于多个用户会话。
    • UGA 的位置:
      • 会话的 UGA (User Global Area) - 包含私有 SQL 区域会话内存 - 必须位于共享内存中,以便不同的共享服务器进程都能访问到它所服务的会话的上下文。
      • 如果配置了 LARGE_POOL_SIZE,UGA 优先放在 SGA 的大池 (Large Pool) 中。
      • 如果没有配置大池或大池空间不足,UGA 会放在 共享池 (Shared Pool) 中。
    • PGA 的内容: 共享服务器进程的 PGA 相对较小,主要包含该进程自身的固定状态和控制信息,不再包含 UGA。
    • 工作区: SQL 工作区(排序区、哈希区等)仍然位于共享服务器进程的 PGA 中。因为它们是进程在执行 SQL 时使用的临时内存,与会话的永久状态(UGA)无关,且不需要在不同进程间共享。
    • 关键点: 在共享服务器模式下,PGA_AGGREGATE_TARGET 只统计所有共享服务器进程的 PGA 中的工作区内存,不包括 UGA(UGA 在 SGA 的大池或共享池中统计)。

五、 PGA 的监控与性能优化关键点

  1. 关键动态性能视图 (V$ Views):

    • V$PROCESS:
      • PGA_USED_MEM: 该进程 PGA 当前已使用的内存量 (Bytes)。
      • PGA_ALLOC_MEM: 该进程 PGA 当前已分配的内存总量 (Bytes - 包括已使用和空闲但尚未释放给操作系统的)。
      • PGA_MAX_MEM: 该进程 PGA 曾经达到过的最大内存量 (Bytes)。
    • V$SESSTAT:
      • 结合 V$STATNAME,查看会话级的 PGA 相关统计:
        • session pga memory: 当前会话使用的 PGA 内存。
        • session pga memory max: 该会话曾经达到的最大 PGA 内存。
        • 工作区统计:
          • workarea memory allocated: 会话当前所有活动工作区分配的内存总和。
          • workarea executions - optimal: 以 OPTIMAL 模式执行的操作次数。
          • workarea executions - onepass: 以 ONEPASS 模式执行的操作次数。
          • workarea executions - multipass: 以 MULTIPASS 模式执行的操作次数。重点关注!高值表示严重问题。
          • sorts (memory): 完全在内存中完成的排序次数。
          • sorts (disk): 需要写磁盘 (临时表空间) 的排序次数。重点关注!
    • V$SYSSTAT:
      • 查看实例级的 PGA 和工作区统计:
        • total PGA allocated: 实例当前分配给所有进程的 PGA 内存总和。
        • total PGA inuse: 实例当前所有进程 PGA 中实际使用的内存总和。
        • total PGA used for auto workareas: 实例当前所有自动管理工作区使用的内存总和。
        • workarea executions - optimal, - onepass, - multipass (实例级汇总)。
        • sorts (memory), sorts (disk) (实例级汇总)。
    • V$PGASTAT:
      • 核心视图! 提供实例级 PGA 的关键摘要信息
        • aggregate PGA target parameter: PGA_AGGREGATE_TARGET 的当前值。
        • aggregate PGA auto target: 可用于自动工作区的 PGA 内存量 (≈ PGA_AGGREGATE_TARGET - 其他固定的 PGA 开销)。
        • total PGA allocated: 当前分配给所有进程的 PGA 总和。
        • total PGA inuse: 当前所有进程 PGA 中实际使用的内存总和。
        • total freeable PGA memory: 可以被操作系统回收的已分配但未使用的 PGA 内存量。
        • over allocation count: 重要指标! 实例启动后,PGA 使用量超过 PGA_AGGREGATE_TARGET 的次数。理想为 0。非 0 表示目标设置过低或存在内存泄漏/失控进程。
        • cache hit percentage: 关键性能指标! 计算得出:100% * (bytes processed / (bytes processed + extra bytes read/written))。它反映了工作区执行的效率。bytes processed 是操作处理的数据量,extra bytes read/writtenONEPASS/MULTIPASS 模式产生的额外临时表空间 I/O 量。越高越好,一般应 >90%。
        • maximum PGA allocated: 实例启动后达到的最大 total PGA allocated
    • V$SQL_WORKAREA / V$SQL_WORKAREA_ACTIVE:
      • 查看当前或历史 SQL 语句的工作区使用情况:
        • SQL_ID, PLAN_HASH_VALUE: 标识 SQL。
        • OPERATION_TYPE: 操作类型 (SORT, HASH-JOIN, BITMAP, etc.)。
        • POLICY: 管理模式 (AUTO - APMM, MANUAL)。
        • ESTIMATED_OPTIMAL_SIZE: 估算达到 OPTIMAL 模式所需内存 (Bytes)。
        • ESTIMATED_ONEPASS_SIZE: 估算达到 ONEPASS 模式所需内存 (Bytes)。
        • LAST_MEMORY_USED: 上次执行实际使用的最大内存 (Bytes)。
        • LAST_EXECUTION: 上次执行模式 (OPTIMAL, ONEPASS, MULTIPASS)。
        • LAST_DEGREE: 并行度。
        • ACTIVE_TIME: (仅 V$SQL_WORKAREA_ACTIVE) 工作区已激活的时间 (ms)。
        • WORK_AREA_SIZE: (仅 V$SQL_WORKAREA_ACTIVE) 当前分配的工作区大小 (Bytes)。
        • EXPECTED_SIZE: (仅 V$SQL_WORKAREA_ACTIVE) Oracle 认为该操作达到 OPTIMAL 所需大小 (Bytes)。
        • ACTUAL_MEM_USED / MAX_MEM_USED / TEMPSEG_SIZE: (仅 V$SQL_WORKAREA_ACTIVE) 内存和临时空间使用详情。
    • V$TEMPSEG_USAGE (关联 DBA_TEMP_FILES):
      • 监控当前正在使用临时表空间的会话和 SQL。可以看到哪个会话/SQL 在写多少临时数据。是诊断 ONEPASS/MULTIPASS 问题的直接证据。
  2. 优化方向:

    • 设置合理的 PGA_AGGREGATE_TARGET:
      • 监控 V$PGASTATcache hit percentageover allocation count。目标:cache hit percentage > 90%over allocation count = 0
      • 使用 V$PGA_TARGET_ADVICE 视图(基于历史工作负载统计)预测不同 PGA_AGGREGATE_TARGET 值对 cache hit percentageover allocation count 的影响。这是最重要的调优工具
      • 根据建议逐步调整目标值。
    • 识别并优化高 PGA 消耗的 SQL:
      • 使用 V$SQL, V$SQLAREA, V$SQLSTATS 结合 V$SQL_WORKAREA 查找:
        • 执行次数多且 LAST_EXECUTIONONEPASS/MULTIPASS 的 SQL。
        • 磁盘排序 (sorts (disk)) 或哈希操作多的 SQL。
        • LAST_MEMORY_USEDESTIMATED_OPTIMAL_SIZE 很大的 SQL。
      • 优化手段:
        • SQL 重写: 消除不必要的排序 (DISTINCT, ORDER BY)、减少处理的数据量 (优化 WHERE 条件、使用更有效的连接方式)。
        • 索引优化: 创建合适的索引避免全表扫描和后续的大排序/哈希。考虑索引覆盖查询。
        • 调整连接方法: 如果哈希连接导致大量 MULTIPASS,尝试使用嵌套循环连接(如果驱动行集小)或归并排序连接(如果数据已排序)。可使用提示 /*+ USE_NL */, /*+ USE_MERGE */ 引导优化器。
        • 增加 _PGA_MAX_SIZE (谨慎!): 对于确实需要处理海量数据的 DSS 查询,如果估算的 OPTIMAL 大小远超默认 200MB 限制且系统资源充足,可考虑增大此隐含参数,使单个操作能获得更多内存。务必充分测试!
    • 优化临时表空间 I/O:
      • 确保临时表空间使用临时文件 (Temp Files) 而非永久数据文件,并放在高性能磁盘(最好独立于数据文件和重做日志文件)上。
      • 考虑使用 TEMPORARY TABLESPACE(如果可用),利用多个临时文件分散 I/O。
      • 监控 V$TEMPSEG_USAGEV$SESSION_WAIT 中与临时表空间相关的等待事件 (direct path read temp, direct path write temp, enq: TS - contention 等)。
    • 审慎使用共享服务器模式:
      • 虽然共享服务器能减少进程数,但将 UGA 放入 SGA 会增加共享池/大池的压力和争用风险。
      • 现代系统通常内存充足,专用服务器模式是更简单、更常见的选择,除非有明确的连接数限制需求。
      • 如果使用共享服务器,务必配置足够大的 LARGE_POOL_SIZE 以避免 UGA 侵占共享池。
    • 监控失控进程:
      • 定期检查 V$PROCESSPGA_USED_MEM/PGA_ALLOC_MEM/PGA_MAX_MEM,识别异常消耗 PGA 的进程(如存在内存泄漏的 Bug)。
      • 结合 V$SESSIONV$SQL 定位具体会话和 SQL。

六、 总结

PGA 是 Oracle 数据库中为每个服务器进程分配的私有内存区域,与共享的 SGA 相辅相成。

  • 核心功能:
    1. 存储会话私有状态: 登录信息、会话设置、绑定变量值、游标状态 (私有 SQL 区域)。
    2. 提供 SQL 工作区: 为内存密集型操作(排序、哈希连接、位图操作、批量装载)提供关键的执行空间。工作区的管理 (OPTIMAL, ONEPASS, MULTIPASS) 是 PGA 性能的核心。
  • 管理核心:
    • PGA_AGGREGATE_TARGET (APMM): 现代 Oracle 数据库的标准配置。DBA 设定实例级 PGA 总目标,Oracle 自动在所有工作区间动态分配内存,优先保证 OPTIMAL 执行。
    • 避免使用过时的手动 *_AREA_SIZE 参数管理。
  • 共享服务器模式差异: UGA (会话状态) 位于 SGA (大池优先),工作区仍在共享服务器进程的 PGA 中。
  • 监控与优化关键:
    • V$PGASTAT:
      • cache hit percentage (>90%)
      • over allocation count (=0)
      • V$PGA_TARGET_ADVICE 指导目标设置。
    • V$SQL_WORKAREA / V$SQL_WORKAREA_ACTIVE:
      • 识别 ONEPASS/MULTIPASS 操作的 SQL。
      • 查看操作估算和实际内存需求。
    • V$SYSSTAT / V$SESSTAT:
      • sorts (disk), workarea executions - multipass
    • V$TEMPSEG_USAGE:
      • 实时监控临时表空间使用。
  • 优化手段:
    • 设置合理的 PGA_AGGREGATE_TARGET (基于建议视图)。
    • 识别并优化高消耗 SQL (消除不必要操作、优化连接、利用索引)。
    • 优化临时表空间 I/O (高性能磁盘、独立存储、临时文件组)。
    • 慎用共享服务器,确保大池充足 (如果使用)。

理解 PGA 的设计原理和管理机制,对于诊断和解决与会话内存、排序、哈希连接相关的性能瓶颈至关重要。结合 SGA 的知识,才能全面掌握 Oracle 数据库的内存管理体系,构建高性能、可扩展的数据库系统。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区