PGA 内存结构与 Private SQL Area
PGA 内存结构与 Private SQL Area
适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
PGA(Program Global Area) 是单个服务器进程私有的内存区,与 SGA 共享内存相对[1]。
核心特性:
- 私有性:每个服务器进程独立 PGA
- 非共享:进程间不互相访问
- 动态分配:按需分配/释放
- 会话级:随会话创建/销毁
2. PGA 主要组件
| 组件 | 作用 |
|---|---|
| Private SQL Area | SQL 绑定变量、执行状态 |
| Sort Area | 排序内存 |
| Hash Area | 哈希连接内存 |
| Bitmap Merge Area | 位图合并 |
| Bitmap Create Area | 位图创建 |
| Stack | 进程栈 |
3. Private SQL Area
3.1 作用
存储会话私有的 SQL 执行状态:
- 绑定变量值
- 排序区域指针
- 游标执行状态
3.2 结构
Private SQL Area
├── Run-time Area(运行时区)
│ ├── 查询执行状态
│ ├── 已读取行数
│ └── 排序状态
└── Persistent Area(持久区)
├── 绑定变量值
└── 排序缓冲区指针
3.3 专用 vs 共享服务器
| 模式 | Private SQL Area 位置 |
|---|---|
| 专用服务器 | PGA 中 |
| 共享服务器 | UGA 中(位于 SGA 的 Shared Pool 或 Large Pool) |
4. Work Area(工作区)
4.1 类型
| 类型 | 用途 |
|---|---|
| Sort Area | ORDER BY、DISTINCT、GROUP BY |
| Hash Area | Hash Join、Hash Group By |
| Bitmap Merge | Bitmap 索引合并 |
| Bitmap Create | Bitmap 索引创建 |
4.2 大小控制
SHOW PARAMETER pga_aggregate_target;
SHOW PARAMETER pga_aggregate_limit;
SHOW PARAMETER workarea_size_policy;
-- AUTO: 自动管理(推荐)
-- MANUAL: 手动(旧版)
4.3 排序区大小
-- 手动模式下的排序区大小
SHOW PARAMETER sort_area_size;
SHOW PARAMETER sort_area_retained_size;
5. PGA 自动管理
5.1 PGA_AGGREGATE_TARGET
-- 设置 PGA 目标总量
ALTER SYSTEM SET pga_aggregate_target=2G SCOPE=BOTH;
-- PGA 单个 Work Area 最大
-- = MIN(pga_aggregate_target * 5%, 100MB)
5.2 PGA_AGGREGATE_LIMIT(12c+)
-- 设置 PGA 硬上限
ALTER SYSTEM SET pga_aggregate_limit=4G SCOPE=BOTH;
-- 超过限制时:
-- 1. 终止内存消耗最大的会话
-- 2. 报 ORA-04036 错误
5.3 自动分配策略
PGA 总量 = pga_aggregate_target
分配规则:
- 单会话串行操作:最多 3% PGA
- 单会话并行操作:最多 50% PGA(分给所有并行进程)
- 多会话共享:动态平衡
6. 相关视图
-- PGA 总体统计
SELECT name, value/1024/1024 AS mb
FROM v$pgastat
WHERE name IN (
'total PGA allocated',
'total PGA used',
'total PGA inuse',
'total freeable PGA memory',
'maximum PGA allocated',
'aggregate PGA target parameter',
'aggregate PGA auto target'
);
-- PGA 内存按会话分布
SELECT
pid,
spid,
program,
pga_used_mem/1024/1024 AS used_mb,
pga_alloc_mem/1024/1024 AS alloc_mb,
pga_max_mem/1024/1024 AS max_mb
FROM v$process
ORDER BY pga_alloc_mem DESC;
-- Work Area 统计
SELECT
work_area_size/1024/1024 AS size_mb,
policy,
optimal_executions,
onepass_executions,
multipasses_executions
FROM v$sql_workarea;
-- Work Area 建议器
SELECT
round(pga_target_for_estimate/1024/1024) AS pga_mb,
estd_pga_cache_hit_percentage AS hit_pct,
estd_overalloc_count AS overalloc
FROM v$pga_target_advice;
7. 排序性能诊断
7.1 监控排序
SELECT name, value
FROM v$sysstat
WHERE name LIKE '%sort%';
-- sort(memory): 内存中完成的排序
-- sort(disk): 写入磁盘的排序
-- 健康标准:sort(memory)/(sort(memory)+sort(disk)) > 95%
7.2 临时表空间使用
SELECT
username,
sql_id,
blocks * 8192/1024/1024 AS mb_used
FROM v$tempseg_usage
ORDER BY blocks DESC;
8. 常见坑与排错
8.1 排序溢出磁盘
现象:sort(disk) 比例高。
修复:
-- 1. 增大 PGA
ALTER SYSTEM SET pga_aggregate_target=4G SCOPE=BOTH;
-- 2. 优化 SQL 减少排序
-- 3. 检查临时表空间大小
SELECT tablespace_name, SUM(bytes)/1024/1024 AS mb
FROM dba_temp_files
GROUP BY tablespace_name;
8.2 ORA-04036: PGA 超过限制
现象:单会话占用 PGA 过多。
修复:
-- 1. 增大 pga_aggregate_limit
ALTER SYSTEM SET pga_aggregate_limit=8G SCOPE=BOTH;
-- 2. 优化消耗内存的 SQL(如大排序/哈希)
SELECT sql_id, pga_used_mem/1024/1024 AS mb
FROM v$sql_workarea_active
ORDER BY pga_used_mem DESC;
8.3 共享服务器 PGA 异常
现象:共享服务器模式下 PGA 使用过大。
原因:UGA 位于 SGA 中,PGA 主要存 Stack。
修复:检查 UGA 在 Shared Pool/Large Pool 的占用。
9. 最佳实践
- 使用 PGA 自动管理:
workarea_size_policy=AUTO - 合理设置 PGA_AGGREGATE_TARGET:通常是 SGA 的 20-30%
- 设置 PGA_AGGREGATE_LIMIT:硬上限 = 2×TARGET
- 监控排序溢出:
sort(memory)比例 > 95% - 优化大排序 SQL:避免不必要的排序
- 临时表空间充足:≥ PGA 大小
- 并行查询注意 PGA:并行度高时 PGA 需求大
10. 参考资料
[1] Oracle Database Concepts 19c, “Program Global Area (PGA)” https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/memory-architecture.html
[2] Oracle Database Administrator’s Guide 19c, “Managing PGA” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-memory.html