Oracle 内存结构 SGA / PGA / UGA 详解

适用版本:Oracle Database 19c / 23ai
阅读基础:了解 Oracle 实例(Instance)的基本概念
文档版本:v1.0 / 2026-07


目录


1. 概述:为什么内存结构是 Oracle 性能的核心

Oracle 数据库的性能瓶颈 80% 以上与内存配置相关。原因在于:

  1. 磁盘 I/O 与内存访问速度差距巨大:磁盘毫秒级(ms),内存纳秒级(ns),相差 6 个数量级
  2. Oracle 是基于缓存(Cache)的数据库:所有数据访问都先经过 SGA 的 Buffer Cache
  3. 解析成本高:SQL 硬解析需要消耗大量 CPU 和共享池内存
  4. 排序/哈希需要内存:PGA 不足会触发临时表空间读写,性能下降 10-100 倍

理解 SGA / PGA / UGA 三个内存区域,是 Oracle 调优和排错的基础。本文基于 Oracle 官方文档 Concepts 第 15 章[1] 与 23ai 新增的 Managed Global Area(MGA)[2],结合社区实战经验,系统讲解。


2. Oracle 内存结构总览

Oracle 实例启动时分配的内存区域分为四大类(23ai 新增 MGA)[1][2]:

┌─────────────────────────────────────────────────────────────┐
│                     Oracle Instance Memory                  │
├─────────────────────────────────────────────────────────────┤
│  SGA (System Global Area)        ── 共享,所有 server/bg    │
│  ├─ Database Buffer Cache                              进程共享
│  ├─ Shared Pool (Library Cache + Data Dict Cache + Result Cache)
│  ├─ Redo Log Buffer                                        │
│  ├─ Large Pool                                             │
│  ├─ Java Pool                                              │
│  ├─ Streams Pool                                           │
│  └─ Fixed SGA                                              │
├─────────────────────────────────────────────────────────────┤
│  PGA (Program Global Area)       ── 私有,每个进程独有       │
│  ├─ Private SQL Area (Session-specific)                    │
│  ├─ SQL Work Area (Sort/Hash/Bitmap)                       │
│  └─ Stack / Control variables                              │
├─────────────────────────────────────────────────────────────┤
│  UGA (User Global Area)          ── 会话级,位置随连接模式变  │
│  └─ Session State(含 PL/SQL 变量、Cursor 状态等)           │
├─────────────────────────────────────────────────────────────┤
│  MGA (Managed Global Area, 23ai) ── 半共享,跨可信进程       │
└─────────────────────────────────────────────────────────────┘

关键关系:

  • PGA 包含 UGA:在专用服务器(Dedicated Server)模式下,UGA 是 PGA 的一部分
  • SGA 包含 UGA:在共享服务器(Shared Server)模式下,UGA 位于 SGA 的 Large Pool(若未配置 Large Pool 则在 Shared Pool)
  • PGA 永远不在 SGA 中:PGA 是进程私有的,绝不会被分配到 SGA 共享内存段中[1]

3. SGA(System Global Area)系统全局区

3.1 SGA 概念与共享特性

SGA 是一组共享内存结构的集合,包含一个 Oracle 数据库实例的数据和控制信息。所有 server 进程和 background 进程都共享 SGA[1]。

特性:

  • 读写共享:所有进程可读,多个进程可并发写不同区域
  • 生命周期:实例启动时分配(startup nomount),实例关闭时释放
  • 共享内存机制:底层通过操作系统 Shared Memory(如 Linux 的 shmget)实现
  • 粒度分配:SGA 以 granule(粒度)为单位动态扩展,128 MB SGA 以下粒度为 4 MB,以上为 16 MB

查看 SGA:

-- 方式一:sqlplus 命令
SQL> SHOW SGA

Total System Global Area  3290345472 bytes
Fixed Size                  2217832 bytes
Variable Size            1795164312 bytes
Database Buffers         1476395008 bytes
Redo Buffers               16568320 bytes

-- 方式二:查询视图
SELECT name, bytes/1024/1024 AS "Size(MB)" FROM v$sga;
SELECT * FROM v$sgainfo;

SGA 各组件大小(典型 OLTP 系统):

组件 占 SGA 比例 典型大小(16 GB SGA) 增长性
Buffer Cache 60-70% 10 GB 自动
Shared Pool 15-25% 3 GB 自动
Redo Log Buffer <1% 128 MB 静态
Large Pool 5-10% 1 GB 自动
Java Pool 1-5% 256 MB 自动
Streams Pool 1-5% 256 MB 自动
Fixed SGA <1% 2 MB 静态

3.2 Database Buffer Cache 数据库高速缓冲区

作用:缓存从数据文件读取的数据块副本,所有用户进程共享。命中则直接读内存,未命中则触发磁盘 I/O[1][3]。

Buffer 的 4 种状态[1]:

状态 含义
Pinned 正在被某个进程访问,其他进程需等待
Clean 内容与磁盘一致,可被立即重用
Free / Unused 从未使用过(实例刚启动)
Dirty 内容被修改过,与磁盘不一致,需 DBWn 写盘后才能重用

管理机制:两个链表[1][3]:

  • LRU List(最近最少使用链表):维护所有 buffer 的访问顺序。包含 free、pinned、未加入 dirty list 的脏块
  • Write List / Dirty List(写链表/脏链表):保存所有 dirty buffer,等待 DBWn 写入磁盘

LRU 算法工作流程[3]:

  1. 用户进程请求数据 → 先在 Buffer Cache 查找(Cache Hit)
  2. 未命中(Cache Miss)→ 需要从磁盘读入 → 在 LRU 链表尾部找 free buffer
  3. 搜索途中遇到 dirty buffer → 移到 Dirty List,继续搜索
  4. 找到 free buffer → 从磁盘读入数据 → 移到 LRU 的 MRU 端
  5. 搜索超过阈值仍未找到 → 触发 DBWn 写脏块

全表扫描的特殊处理[1]:

全表扫描读入的数据块会被放到 LRU 链表尾部(而非 MRU 端),这样大表扫描不会冲掉热点数据。可通过 CACHE hint 改变此行为。

Multiple Buffer Pool[3]:

-- 配置三种 buffer pool
ALTER SYSTEM SET db_cache_size = 8G;
ALTER SYSTEM SET db_keep_cache_size = 2G;     -- KEEP 池
ALTER SYSTEM SET db_recycle_cache_size = 1G;  -- RECYCLE 池

-- 将对象指定到对应池
ALTER TABLE hot_table STORAGE (BUFFER_POOL KEEP);
ALTER TABLE archive_table STORAGE (BUFFER_POOL RECYCLE);
池 用途 LRU 策略
Default 默认池 标准 LRU
Keep 经常访问的小表/索引 尽量不淘汰
Recycle 很少重用的数据(如大表扫描结果) 快速淘汰

非默认块大小 Buffer:

-- 配置 2K/4K/16K/32K 缓冲池(用于传输表空间)
ALTER SYSTEM SET db_16k_cache_size = 1G;

坑 1:db_2k_cache_size 等不能用于标准块大小(如标准块是 8K,则 db_8k_cache_size 不存在,由 db_cache_size 配置)。

3.3 Shared Pool 共享池

作用:缓存可被多个会话共享的各种结构,是 SGA 中最复杂的组件[1][3]。

核心子组件:

3.3.1 Library Cache 库缓存

存储已解析和执行的 SQL、PL/SQL 代码、Java 类等。包含:

  • Shared SQL Area:每条 SQL 语句的解析树、执行计划、统计信息
  • Shared PL/SQL Area:存储过程、函数、包、触发器的解析代码
  • Control structures:锁、library cache handle 等

SQL 共享的条件(必须字符级完全一致):

  • 文本字符完全相同(包括大小写、空格、换行)
  • 引用的对象 schema 相同
  • 绑定变量类型与长度相近
  • 优化器模式相同
  • NLS 环境一致

坑 2:以下两条 SQL 在 Library Cache 中是不同的 cursor:

SELECT * FROM emp WHERE empno = 7900;
SELECT * FROM emp WHERE empno = 7900;   -- 末尾多一个空格

这就是为什么生产环境必须用绑定变量:

-- ✅ 推荐:使用绑定变量,可被多个会话共享
SELECT * FROM emp WHERE empno = :1;

-- ❌ 避免:字面值 SQL,每次值不同都触发硬解析
SELECT * FROM emp WHERE empno = 7900;
SELECT * FROM emp WHERE empno = 7901;

3.3.2 Data Dictionary Cache 数据字典缓存

又称 Row Cache,缓存数据字典表的内容(如 SYS.OBJ$、SYS.USER$、SYS.TS$ 等)。

作用:解析 SQL 时无需反复读 SYSTEM 表空间的数据文件。

3.3.3 Result Cache 结果缓存

缓存查询结果,下次相同查询直接返回缓存结果(11g 引入)。

-- 启用结果缓存
ALTER SYSTEM SET result_cache_mode = FORCE;
ALTER SYSTEM SET result_cache_max_size = 1G;

-- 在查询中使用 hint
SELECT /*+ result_cache */ * FROM products WHERE category = 'PHONES';

适用场景:查询结果稳定不变(如静态字典表)、查询本身计算量大。

坑 3:Result Cache 对频繁更新的表是性能杀手,因为每次 DML 都会使其失效并重新构建。

3.4 Redo Log Buffer 重做日志缓冲区

作用:缓存 redo entries(重做条目),暂存于内存中,由 LGWR 异步写入在线 redo log 文件[1]。

特性:

  • 大小由 LOG_BUFFER 参数控制,默认 14 MB,不能动态调整
  • 循环使用(circular buffer)
  • 任何 DML/DDL 操作都会产生 redo entry

LGWR 写入触发条件[1]:

  1. 用户提交(COMMIT)
  2. Redo Log Buffer 三分之一满(1/3 full)
  3. Redo Log Buffer 中未写入数据达到 1 MB
  4. 每 3 秒一次(DBWR 写之前)
  5. 切换日志文件(log switch)

坑 4:LOG_BUFFER 太小会导致频繁的 LGWR 写入,引发 log file sync 等待事件。生产环境建议 ≥ 64 MB。

3.5 Large Pool 大池

作用:可选的 SGA 区域,用于缓冲大块 I/O 请求,避免 Shared Pool 内存碎片[1]。

使用场景:

  • RMAN 备份恢复时的 I/O buffer
  • 共享服务器(Shared Server)模式下的 UGA
  • 并行查询(Parallel Query)的消息缓冲区
  • Oracle Streams / GoldenGate

配置:

ALTER SYSTEM SET large_pool_size = 1G;

坑 5:启用共享服务器模式但未配置 Large Pool 时,UGA 会从 Shared Pool 分配,导致 Shared Pool 严重碎片化、library cache latch 争用。

3.6 Java Pool Java 池

作用:在数据库中运行 Java 存储过程(CREATE JAVA)时的 JVM 内存[1]。

ALTER SYSTEM SET java_pool_size = 256M;

未使用 Java 存储过程的数据库可设为 0。

3.7 Streams Pool 流池

作用:Oracle Streams、LogMiner、GoldenGate 使用的内存区域[1]。

ALTER SYSTEM SET streams_pool_size = 512M;

启用 GoldenGate 或 Streams 时必须配置。

3.8 Fixed SGA 固定区

作用:包含 Oracle 内部的指针、状态变量、数据结构等管理信息,与具体数据库无关[1]。

大小固定(几 MB),不可配置,由 Oracle 自动分配。

3.9 Result Cache 结果缓存

(见 3.3.3,独立组件视角)


4. PGA(Program Global Area)程序全局区

4.1 PGA 概念与私有特性

PGA 是 Oracle 进程私有的内存区域,包含该进程专属的数据和控制信息。PGA 不在 SGA 中分配,永远不会被其他进程共享[1]。

特性:

  • 每个服务器进程(Server Process)和后台进程(Background Process)都有自己的 PGA
  • 进程启动时分配,结束时释放
  • 实例 PGA = 所有进程 PGA 的总和
  • 由 PGA_AGGREGATE_TARGET 控制总大小(自动管理模式)

查看 PGA:

SELECT name, value/1024/1024 AS "MB" FROM v$pgastat;

4.2 PGA 内部结构

┌──────────────────────────────────────┐
│             PGA (per process)         │
├──────────────────────────────────────┤
│  1. Stack Area                       │  -- 进程栈,保存本地变量
│  2. Session Memory (if dedicated)    │  -- 专用服务器下 = UGA
│  3. Private SQL Area                 │
│     ├─ Persistent Area              │  -- 绑定变量信息,cursor 关闭时释放
│     └─ Runtime Area                 │  -- 执行时使用
│  4. SQL Work Area                    │
│     ├─ Sort Area                    │  -- 排序
│     ├─ Hash Area                    │  -- 哈希连接
│     └─ Bitmap Merge Area            │  -- 位图索引合并
└──────────────────────────────────────┘

4.3 Private SQL Area 私有 SQL 区

存储每个会话独有的 SQL 执行状态,与 Shared Pool 中的 Shared SQL Area(共享部分)对应[1]。

子区域 内容 生命周期
Persistent Area 绑定变量值、安全上下文 Cursor 关闭时释放
Runtime Area 执行时状态(当前行、排序进度等) 执行第一步时分配,执行结束释放

专用 vs 共享服务器下 Private SQL Area 位置[1]:

  • 专用服务器:Private SQL Area 在 PGA 中
  • 共享服务器:Persistent Area 在 SGA 的 Large Pool 中(因为会话可能切换服务器进程),Runtime Area 仍在 PGA 中

4.4 SQL Work Area SQL 工作区

PGA 中最重要的性能相关区域,决定排序/哈希/位图操作是否在内存完成[1]。

工作区 用于 不足时降级
Sort Area ORDER BY、GROUP BY、DISTINCT、UNION、索引创建 写入 TEMP 表空间
Hash Area Hash Join、Hash Group By 写入 TEMP 表空间
Bitmap Merge Area 位图索引合并 性能显著下降
Bitmap Create Area 位图索引创建 性能下降

性能影响:

  • 内存中完成(in-memory):纳秒级
  • 单次写盘(1-pass):毫秒级,慢 1000 倍
  • 多次写盘(multi-pass):性能灾难

4.5 PGA 自动管理

由 WORKAREA_SIZE_POLICY = AUTO + PGA_AGGREGATE_TARGET 启用[4]。

-- 启用自动 PGA 管理
ALTER SYSTEM SET workarea_size_policy = AUTO;
ALTER SYSTEM SET pga_aggregate_target = 4G;

-- 单个 SQL 工作区上限
-- 由 _pga_max_size 决定(默认 200 MB,可调)
-- 超过部分会自动写入 TEMP

经验配比[4]:

系统类型 PGA 占总内存 说明
OLTP 20% 排序/哈希少
DSS / 数据仓库 50% 大量排序、Hash Join
混合 30% 折中

查看 PGA 顾问建议:

SELECT pga_target_for_estimate / 1024 / 1024 AS "PGA Target(MB)",
       estd_pga_cache_hit_percentage AS "Cache Hit(%)",
       estd_overalloc_count AS "Overalloc"
FROM v$pga_target_advice;

5. UGA(User Global Area)用户全局区

5.1 UGA 与连接模式的关系

UGA 是会话级内存,存储会话状态(session state),其位置取决于连接模式[1]:

连接模式 UGA 位置 原因
专用服务器(Dedicated Server) PGA 中 一个会话绑定一个进程,进程私有内存即可
共享服务器(Shared Server) SGA 的 Large Pool 中(未配置时在 Shared Pool) 会话在不同服务器进程间切换,必须共享
DRCP(Database Resident Connection Pooling) SGA 中 类似共享服务器

5.2 UGA 内容

UGA 包含会话相关的所有状态[1]:

  • 会话变量:PL/SQL 包变量、会话级变量
  • 登录信息:用户身份、权限、角色
  • Cursor 状态:打开的 cursor、当前 fetch 位置
  • Sort Area 的 Retained 部分:SORT_AREA_RETAINED_SIZE,cursor 关闭前仍保留
  • OLAP 页缓存(如启用)

查看 UGA:

SELECT name, value FROM v$statname n, v$sesstat s
WHERE n.statistic# = s.statistic#
  AND n.name LIKE '%uga%'
  AND s.sid = USERENV('SID');

6. 内存管理方式对比

6.1 手动内存管理

逐个设置每个组件大小:

ALTER SYSTEM SET db_cache_size = 8G;
ALTER SYSTEM SET shared_pool_size = 3G;
ALTER SYSTEM SET pga_aggregate_target = 4G;
ALTER SYSTEM SET large_pool_size = 1G;
ALTER SYSTEM SET java_pool_size = 256M;
-- ...

适用场景:老版本兼容(9i 之前)、特殊调优、问题排查。

缺点:组件间不能动态调配,配置繁琐。

6.2 ASMM 自动共享内存管理

只需设置 SGA_TARGET,SGA 内部各组件自动调整(PGA 需单独配置)[1]。

ALTER SYSTEM SET sga_target = 16G SCOPE=BOTH;
ALTER SYSTEM SET pga_aggregate_target = 4G SCOPE=BOTH;

-- 仍可设置下限保护
ALTER SYSTEM SET db_cache_size = 4G;       -- 至少 4G
ALTER SYSTEM SET shared_pool_size = 2G;    -- 至少 2G

特点:

  • 只能动态减少未使用的内存,不能从有数据的区域抢
  • 与 HugePages 兼容(推荐)
  • 19c 默认模式

6.3 AMM 自动内存管理

只需设置 MEMORY_TARGET,SGA 与 PGA 之间自动调配[1]:

ALTER SYSTEM SET memory_target = 20G;
ALTER SYSTEM SET memory_max_target = 24G;

坑 6:AMM 与 HugePages 不兼容[1]

AMM 使用 MEMORY_TARGET 创建的共享内存段在动态调整时,会破坏 HugePages 的连续性。生产环境强制要求 HugePages,因此生产环境禁用 AMM,使用 ASMM。

6.4 Unified Memory 统一内存管理(23ai)

23ai 引入新参数 MEMORY_SIZE,统一管理 SGA / PGA / MGA / UGA[2]:

ALTER SYSTEM SET memory_size = 20G;

MGA(Managed Global Area)[2]:23ai 新增的半共享内存区域,可被一组受信任的 Oracle 进程动态共享,比 SGA 更灵活。

6.5 三种管理方式选择决策

是否生产环境?
├─ 是 → 启用 HugePages → ASMM(推荐)
└─ 否(开发/测试)
   ├─ 内存 < 8 GB → AMM
   └─ 内存 ≥ 8 GB → ASMM
场景 推荐模式 关键参数
生产 OLTP ASMM SGA_TARGET + PGA_AGGREGATE_TARGET + HugePages
生产 DSS ASMM 同上,PGA 占比更高
开发测试 AMM MEMORY_TARGET
老系统升级 手动 保持原配置
23ai 新建库 Unified Memory MEMORY_SIZE

7. 内存监控与诊断视图

7.1 SGA 相关视图

-- SGA 总览
SELECT * FROM v$sga;
SELECT * FROM v$sgainfo;

-- SGA 动态组件
SELECT component, current_size/1024/1024 AS "MB"
FROM v$sga_dynamic_components;

-- SGA 顾问建议
SELECT sga_size, sga_size_factor, estd_db_time_factor
FROM v$sga_target_advice;

-- SGA resize 操作历史
SELECT * FROM v$sga_resize_ops;

7.2 PGA 相关视图

-- PGA 总览
SELECT name, value/1024/1024 AS "MB" FROM v$pgastat;

-- PGA 进程级详情
SELECT spid, program, pga_used_mem, pga_alloc_mem, pga_max_mem
FROM v$process
ORDER BY pga_alloc_mem DESC;

-- PGA 顾问建议
SELECT pga_target_for_estimate/1024/1024 AS "MB",
       estd_pga_cache_hit_percentage
FROM v$pga_target_advice;

-- 工作区使用
SELECT sql_id, operation_type, policy, last_memory_used/1024/1024 AS "MB",
       last_execution
FROM v$sql_workarea
ORDER BY last_memory_used DESC;

7.3 UGA / Session 相关视图

-- 每个会话的内存
SELECT se.sid, se.username,
       s.value/1024/1024 AS "UGA(MB)",
       p.value/1024/1024 AS "PGA(MB)"
FROM v$session se, v$sesstat s, v$statname sn, v$sesstat p, v$statname pn
WHERE se.sid = s.sid
  AND s.statistic# = sn.statistic#
  AND sn.name = 'session uga memory'
  AND se.sid = p.sid
  AND p.statistic# = pn.statistic#
  AND pn.name = 'session pga memory'
ORDER BY s.value DESC;

-- 系统级内存总览
SELECT * FROM v$memory_dynamic_components;

7.4 关键等待事件

等待事件 含义 调优方向
free buffer waits 找不到 free buffer 增大 Buffer Cache、检查 DBWn
buffer busy waits buffer 被占用 减少热点块、调整 PCTFREE
latch: shared pool Shared Pool 闩锁争用 使用绑定变量、增大 Shared Pool
latch: cache buffers chains Buffer Cache 闩锁争用 减少热点块、增加 DBWn
library cache lock Library Cache 锁 检查 DDL 与硬解析
log file sync 提交时等 LGWR 增大 Redo Log Buffer、检查磁盘 I/O
direct path read temp 排序/哈希写盘 增大 PGA

8. 常见坑与最佳实践

坑 1:HugePages 未启用导致 Page Walk 开销

现象:SGA 较大(> 8 GB)时实例启动慢,alert log 警告。

原因:默认 4 KB 页面管理大内存会产生大量页表项,CPU 浪费在 page table walk。

解决:

# 1. 计算所需大页数(每页 2 MB)
# 所需大页数 = SGA_SIZE_MB / 2
# 例如 SGA 16 GB → 8192 / 2 = 4096 大页

# 2. 配置 sysctl
echo "vm.nr_hugepages = 4096" >> /etc/sysctl.conf
sysctl -p

# 3. 关闭 AMM(与 HugePages 不兼容)
ALTER SYSTEM SET memory_target = 0;

# 4. 重启系统
reboot

# 5. 验证
grep Huge /proc/meminfo

坑 2:未用绑定变量导致 Shared Pool 撑爆

现象:v$librarycache 中 SQL AREA 的 gethitratio < 90%,shared pool latch 争用严重。

解决:

-- 1. 设置 cursor_sharing(临时方案,有副作用)
ALTER SYSTEM SET cursor_sharing = FORCE SCOPE=BOTH;
-- 强制将字面值替换为系统生成的绑定变量,可能引发 ACS 问题

-- 2. 根本方案:改代码用绑定变量

-- 3. 检查未共享的 SQL
SELECT sql_id, executions, sql_text
FROM v$sql
WHERE parsing_schema_name = 'YOURAPP'
  AND plan_hash_value = 0
ORDER BY sql_id
FETCH FIRST 100 ROWS ONLY;

坑 3:PGA 设置过大导致 OOM

现象:实例崩溃,alert log 报 ORA-04030: out of process memory。

原因:PGA_AGGREGATE_TARGET 设置过高,叠加 SGA 后超过物理内存。

解决:

-- 1. 检查 PGA 实际使用
SELECT SUM(pga_alloc_mem)/1024/1024/1024 AS "PGA Allocated(GB)"
FROM v$process;

-- 2. 限制单个 SQL 工作区上限
ALTER SYSTEM SET "_pga_max_size" = 2147483648;  -- 2 GB

-- 3. 调整 PGA_AGGREGATE_TARGET
ALTER SYSTEM SET pga_aggregate_target = 2G;

坑 4:Buffer Cache 过小导致 cache hit 低

现象:AWR 中 Buffer Cache Hit Ratio < 90%,db file sequential read 等待高。

解决:

-- 1. 查看命中率
SELECT 1 - (physical.value - direct.value - log.value) / buffer.value AS "Cache Hit Ratio"
FROM v$sysstat physical, v$sysstat direct, v$sysstat log, v$sysstat buffer
WHERE physical.name = 'physical reads'
  AND direct.name = 'physical reads direct'
  AND log.name = 'physical reads direct (lob)'
  AND buffer.name = 'session logical reads';

-- 2. 查看 Buffer Cache 顾问建议
SELECT size_for_estimate/1024/1024 AS "Size(MB)",
       size_factor, estd_physical_read_time
FROM v$db_cache_advice
WHERE buffer_pool = 'DEFAULT';

-- 3. 增大 Buffer Cache
ALTER SYSTEM SET db_cache_size = 16G;

坑 5:Shared Pool 过大反而性能下降

现象:把 Shared Pool 调到 32 GB 后,library cache latch 争用反而增加。

原因:Shared Pool 越大,hash chain 越长,latch 争用概率越高。

解决:Shared Pool 不是越大越好,经验上限 4-8 GB。超过时应优化 SQL 共享而非加内存。

最佳实践总结

  1. 生产环境必用 ASMM + HugePages,禁用 AMM
  2. PGA 与 SGA 比例:OLTP 1:4,DSS 1:1
  3. SGA_TARGET 不超过物理内存 70-80%,留出 OS 与 PGA 空间
  4. 必须用绑定变量,并监控 v$sql 中相似 SQL 数量
  5. 定期收集 AWR 报告,关注 Top 等待事件
  6. Shared Pool 控制在 4-8 GB,超过就优化 SQL 而非加内存
  7. Redo Log Buffer ≥ 64 MB,避免 LGWR 频繁写
  8. 启用 Large Pool(共享服务器、并行查询、RMAN 场景)
  9. 保留 1-2 GB 内核缓冲给 OS,避免 swap
  10. 23ai 新库用 Unified Memory,简化管理

9. 常见问题 FAQ

Q1: SGA_TARGET 和 SGA_MAX_SIZE 的区别?

  • SGA_TARGET:当前 ASMM 目标值,可在 ALTER SYSTEM 中动态调整,上限是 SGA_MAX_SIZE
  • SGA_MAX_SIZE:SGA 上限,需重启实例才能修改
  • 建议:SGA_MAX_SIZE 设为物理内存上限的 70%,SGA_TARGET 初始设为预期值,留出扩展空间

Q2: PGA_AGGREGATE_TARGET 和 PGA_AGGREGATE_LIMIT 的区别?

  • PGA_AGGREGATE_TARGET:目标值,Oracle 尽量不超过(软限制)
  • PGA_AGGREGATE_LIMIT(12c+):硬限制,超过时会中止最耗 PGA 的会话
  • 推荐:LIMIT = 2 * TARGET 或物理内存的 1.5 倍,取较小者

Q3: 如何判断是否需要增加 Buffer Cache?

-- 1. 看命中率(< 95% 值得考虑)
SELECT 1 - SUM(decode(name, 'physical reads', value, 0)) /
       SUM(decode(name, 'session logical reads', value, 0)) AS hit_ratio
FROM v$sysstat WHERE name IN ('physical reads', 'session logical reads');

-- 2. 看顾问建议
SELECT size_factor, estd_physical_read_factor
FROM v$db_cache_advice WHERE buffer_pool = 'DEFAULT';
-- estd_physical_read_factor < 1.0 说明增大有收益

Q4: Shared Pool Free Memory 很大但还是 latch 争用?

这说明碎片化严重,而非内存不够。

-- 查看碎片
SELECT pool, name, bytes/1024/1024 AS "MB"
FROM v$sgastat
WHERE pool = 'shared pool' AND name = 'free memory';

-- 刷共享池(谨慎,会强制所有 cursor 重新解析)
ALTER SYSTEM FLUSH SHARED_POOL;

Q5: AMM 与 HugePages 不兼容如何取舍?

生产环境选 HugePages:

  • HugePages 提升 SGA 访问性能 5-15%
  • AMM 的便利性不如性能重要
  • 19c 起 Oracle 官方文档明确推荐生产用 ASMM + HugePages[1]

10. 参考资料

[1] Oracle Database 19c 概念文档,第 15 章 Memory Architecture:
https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/memory-architecture.html

[2] Oracle Database 23ai 概念文档,第 17 章 Memory Architecture(含 MGA / Unified Memory):
https://docs.oracle.com/en/database/oracle/oracle-database/23/cncpt/memory-architecture.html

[3] Oracle Database Memory Architecture 官方文档(含 LRU/Write List 工作机制):
https://docs.oracle.com/cd/A58617_01/server.804/a58227/ch_mem.htm

[4] 周同学带您玩 AI,《解析 Oracle 数据库架构:实例、内存和进程的完美结合》,墨天轮:
https://www.modb.pro/db/1822855013329285120

[5] 墨天轮,《Oracle 体系结构概览(二)》:
https://www.modb.pro/db/104874

[6] Oracle Database Reference 19c,初始化参数文档:
https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/

[7] Oracle Database Performance Tuning Guide 19c,内存调优章节:
https://docs.oracle.com/en/database/oracle/oracle-database/19/tgdba/


相关文章
- SGA 各组件作用与配置详解
- Database Buffer Cache 工作原理
- Shared Pool 深度解析
- PGA 自动管理与 Work Area
- HugePages 配置与性能优化