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

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 Cache60-70%10 GB自动
Shared Pool15-25%3 GB自动
Redo Log Buffer<1%128 MB静态
Large Pool5-10%1 GB自动
Java Pool1-5%256 MB自动
Streams Pool1-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;

坑 1db_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)

坑 4LOG_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 AreaORDER BYGROUP BYDISTINCTUNION、索引创建写入 TEMP 表空间
Hash AreaHash 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 占总内存说明
OLTP20%排序/哈希少
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
场景推荐模式关键参数
生产 OLTPASMMSGA_TARGET + PGA_AGGREGATE_TARGET + HugePages
生产 DSSASMM同上,PGA 占比更高
开发测试AMMMEMORY_TARGET
老系统升级手动保持原配置
23ai 新建库Unified MemoryMEMORY_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 waitsbuffer 被占用减少热点块、调整 PCTFREE
latch: shared poolShared Pool 闩锁争用使用绑定变量、增大 Shared Pool
latch: cache buffers chainsBuffer Cache 闩锁争用减少热点块、增加 DBWn
library cache lockLibrary 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$librarycacheSQL AREAgethitratio < 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/


相关文章