Oracle内存结构SGA与PGA
Oracle 内存结构决定 SQL 解析、数据块缓存、排序哈希、并发会话和后台任务的效率。SGA 侧重共享,PGA 侧重会话私有,内存调优必须结合负载类型、等待事件和 SQL 行为。
# 1. 学习目标与定位
| 维度 | 内容 |
|---|---|
| 难度层级 | 核心到调优 |
| 核心目标 | 从底层运行链路理解本篇主题,能把概念、SQL、指标、故障和工程取舍连起来 |
| 适合人群 | 开发人员关注硬解析、排序哈希和返回数据量;运维人员关注 SGA/PGA 分配、命中率、等待事件和内存抖动。 |
# 2. 核心概念总览
Oracle内存结构SGA与PGA
├─ SGA
├─ Database Buffer Cache
├─ Shared Pool
├─ Library Cache
├─ Data Dictionary Cache
├─ Redo Log Buffer
├─ Large Pool
├─ PGA
└─ Workarea
这张图只用来定位本章范围。正文不会把每个词机械拆成固定问答,而是按 Oracle 的真实运行机制解释它们之间如何协作、在哪里影响开发、在哪里影响运维。
# 3. 底层原理详解
SGA 是所有会话共享的内存区域。Buffer Cache 缓存数据块,Shared Pool 缓存 SQL 游标、执行计划和数据字典,Redo Log Buffer 暂存 Redo 记录。PGA 属于进程私有,承载排序、哈希、会话变量和游标运行状态。
Oracle 调优不是简单把内存调大。硬解析高说明 SQL 不能复用,Buffer Cache 命中低可能是全表扫描或缓存污染,PGA 不足会让排序和哈希溢写到临时表空间,内存过大也可能挤压操作系统页缓存或触发 NUMA/HugePages 问题。
内存问题常以等待事件形式出现,例如 library cache lock/pin、latch/mutex、direct path read temp、log buffer space、free buffer waits。正确做法是从等待和 SQL 行为回推内存结构,而不是先改参数。
# 4. 关键机制拆解
# 4.1. Buffer Cache 与数据块生命周期
Oracle 读取表和索引时以数据块为单位。块进入 Buffer Cache 后,后续访问可以直接命中内存;修改块时会变成脏块,DBWn 在检查点、缓存压力或后台调度下写回数据文件。
缓存命中率不是唯一指标。大量一次性报表扫描可能污染缓存,热点块争用可能让缓存命中很高但延迟仍然差。要结合 SQL 类型、等待事件和对象访问模式判断。
# 4.2. Shared Pool 与硬解析
Shared Pool 存放解析后的游标、执行计划和数据字典缓存。SQL 文本、Schema、权限、NLS 环境和绑定变量等因素会影响游标复用。硬解析需要语法语义检查、优化器计算和共享池分配,成本远高于软解析。
开发人员使用绑定变量可以显著减少硬解析,但也要关注绑定变量窥探和数据倾斜。运维人员看到 parse time、library cache 等等待时,要同时检查应用 SQL 文本是否大量使用字面量。
# 4.3. PGA、Workarea 与临时空间
排序、哈希连接、位图操作和批处理会使用 PGA Workarea。如果 PGA 不足,操作会分多次执行并落到临时表空间,表现为 direct path read/write temp 和 TEMP 使用暴涨。
这类问题常被误判为磁盘慢,实际根因可能是 SQL 返回行数过大、连接顺序错误、统计信息失真或 PGA 参数不足。调参前要先看执行计划和临时段消耗。
# 4.4. 自动内存管理与生产边界
Oracle 支持自动管理 SGA/PGA,但自动不等于无需治理。核心系统应根据负载类型设置合理上下限,并在变更后观察 AWR、内存顾问、OS 内存和 HugePages。
内存调优要避免“今天慢就加内存”的短视做法。更高质量的路径是减少硬解析、治理大 SQL、隔离报表负载、稳定执行计划,再调整参数。
# 5. 功能模块细节补充
本节围绕概念图中的模块逐个补充底层细节,重点讲它们在 Oracle 运行链路中的位置和相互关系,而不是按固定角色模板拆分。
# 5.1. SGA
SGA 是实例与数据库协作链路中的组成部分。实例侧负责运行时内存、进程和调度,数据库侧负责控制文件、数据文件和日志文件;该模块的异常通常会反映到启动阶段、后台进程等待、告警日志或恢复流程中。
# 5.2. Database Buffer Cache
Database Buffer Cache 是实例与数据库协作链路中的组成部分。实例侧负责运行时内存、进程和调度,数据库侧负责控制文件、数据文件和日志文件;该模块的异常通常会反映到启动阶段、后台进程等待、告警日志或恢复流程中。
# 5.3. Shared Pool
Shared Pool 位于客户端到数据库的连接链路中。它可能参与服务发现、认证、会话创建、SQL 执行、连接复用或补丁管理;排查连接问题时要沿 DNS、监听、服务注册、驱动、连接池、数据库会话限制逐层收敛,而不是只看一个 ORA 错误。
# 5.4. Library Cache
Library Cache 是实例与数据库协作链路中的组成部分。实例侧负责运行时内存、进程和调度,数据库侧负责控制文件、数据文件和日志文件;该模块的异常通常会反映到启动阶段、后台进程等待、告警日志或恢复流程中。
# 5.5. Data Dictionary Cache
Data Dictionary Cache 是实例与数据库协作链路中的组成部分。实例侧负责运行时内存、进程和调度,数据库侧负责控制文件、数据文件和日志文件;该模块的异常通常会反映到启动阶段、后台进程等待、告警日志或恢复流程中。
# 5.6. Redo Log Buffer
Redo Log Buffer 是实例与数据库协作链路中的组成部分。实例侧负责运行时内存、进程和调度,数据库侧负责控制文件、数据文件和日志文件;该模块的异常通常会反映到启动阶段、后台进程等待、告警日志或恢复流程中。
# 5.7. Large Pool
Large Pool 位于客户端到数据库的连接链路中。它可能参与服务发现、认证、会话创建、SQL 执行、连接复用或补丁管理;排查连接问题时要沿 DNS、监听、服务注册、驱动、连接池、数据库会话限制逐层收敛,而不是只看一个 ORA 错误。
# 5.8. PGA
PGA 是实例与数据库协作链路中的组成部分。实例侧负责运行时内存、进程和调度,数据库侧负责控制文件、数据文件和日志文件;该模块的异常通常会反映到启动阶段、后台进程等待、告警日志或恢复流程中。
# 5.9. Workarea
Workarea 是实例与数据库协作链路中的组成部分。实例侧负责运行时内存、进程和调度,数据库侧负责控制文件、数据文件和日志文件;该模块的异常通常会反映到启动阶段、后台进程等待、告警日志或恢复流程中。
# 6. 开发人员重点提醒
- 使用绑定变量,避免海量字面量 SQL 冲击 Shared Pool。
- 分页、报表和批处理要控制返回量、排序列和中间结果规模。
- 不要在应用层无限并发提交大查询,PGA 和 TEMP 会被迅速打满。
# 7. 运维人员重点提醒
- 关注 DB Cache、Shared Pool、PGA、TEMP、硬解析率和相关等待事件。
- 变更内存参数前后对比 AWR,不只看命中率。
- 为大内存主机规划 HugePages,并避免 swap 参与数据库运行。
# 8. 典型问题与排查
- 硬解析高:检查 SQL 字面量、绑定变量、游标共享和应用连接池。
- TEMP 暴涨:定位 SQL_ID、执行计划、排序哈希节点和统计信息。
- free buffer waits:检查 DBWn、IO、脏块比例和检查点压力。
# 9. 实践建议与检查清单
- 硬解析率可控
- PGA/TEMP 有基线
- Buffer Cache 不被报表污染
- HugePages 策略明确
- 内存变更有 AWR 对比
# 10. 阶段小结
本篇的学习重点不是记住术语,而是能把底层机制、业务语义和生产证据连起来。读完本篇后,应该能解释关键组件如何协作、常见问题为什么发生、开发侧如何避免制造风险、运维侧如何用指标和日志把问题定位到具体链路。