备库内存耗尽的典型表现是mrp0进程卡在wait_for_log或applying_log且sequence#停滞,v$sgastat中free memory趋零,sga/pga使用率超95%,并可能触发ora-04030或oom killer杀进程。
备库内存耗尽的典型表现是什么
Active Data Guard 备库一旦内存不足,最直接的信号不是报错,而是同步进程卡住或变慢——MRP0 进程状态长期为 WAIT_FOR_LOG 或 APPLYING_LOG 但 sequence# 不再推进;同时 v$sgastat 中 free memory 接近零,gv$memory_dynamic_components 显示 SGA_TARGET 和 PGA_AGGREGATE_TARGET 实际使用率持续 >95%。更隐蔽的是:备库能连上、能查视图、甚至能执行简单查询,但一跑报表或大表扫描就触发 ORA-04030(out of process memory)或直接被 OS OOM killer 杀掉 ora_pmon 进程。
- 真实场景中,RAC 环境下常只有一节点先出问题,另一节点看似正常,但其实只是还没轮到它处理积压日志
- 不要只看
top 的 %MEM,Oracle 进程的 PGA 是私有内存,ps aux --sort=-%mem 看不到真实压力点
-
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE 能启动 MRP,但不等于它能持续运行——内存不足时它会反复中断重连,日志里留下大量 Media Recovery Waiting for thread 循环
SGA 和 PGA 应该设多大才安全
Active Data Guard 备库的内存配置不能照搬主库。主库要扛写+读+解析+缓存,而备库核心任务只有两件:接收 redo、apply redo。所以它的 SGA 可大幅压缩,PGA 则需留足空间应对大事务 apply(尤其主库做了大批量 DML 后)。
-
SGA_TARGET 建议设为物理内存的 30%~40%,上限不超过 50%;若备库还承担只读报表负载,可上浮至 45%,但必须预留至少 2GB 给 OS 缓存和 Oracle 后台进程
-
PGA_AGGREGATE_TARGET 建议设为 SGA_TARGET 的 30%~50%,且绝对值不低于 2GB(小内存服务器除外);因为 MRP 进程 apply 大事务时,排序/哈希操作全靠 PGA,设太小会导致频繁磁盘临时段写入,拖垮 apply 速度
- 必须禁用
MEMORY_TARGET —— 它会让 Oracle 自动在 SGA/PGA 间挪内存,而 ADG 的 apply 流程对 PGA 稳定性极度敏感,自动调整反而引发抖动
怎么验证当前设置是否真起效了
改完参数不是重启数据库就完事。ADG 备库的内存组件是动态生效的,但 MRP 进程不会自动 reload,得手动干预才能让新 PGA 分配策略覆盖正在运行的 apply 进程。
- 先确认参数已持久化:
SHOW PARAMETER sga_target 和 SHOW PARAMETER pga_aggregate_target
- 再检查实际分配:
SELECT component, current_size/1024/1024 MB FROM v$memory_dynamic_components WHERE component IN ('SGA Target', 'PGA Aggregate Target');
- 最关键一步:停掉并重启 MRP:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; → ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
(这会杀死旧 MRP 并拉起新进程,新进程才会按更新后的 PGA 设置初始化私有内存)
- 观察 5 分钟内
gv$managed_standby 的 status 是否稳定在 APPLYING_LOG,且 block# 持续递增
为什么清理 OS 缓存有时比调参数还管用
Oracle 在 ADG 备库上 apply redo 时,会高频访问数据文件块,这些块被 Linux page cache 缓存后,如果长时间没被换出,就会挤占本该留给 Oracle 进程的可用内存。尤其当备库同时跑着 BI 查询,OS 缓存可能吃掉 30%+ 物理内存,而 free -h 却显示 “available” 数值尚可——这是假象。
- 不要用
echo 3 > /proc/sys/vm/drop_caches 在生产环境乱清,它会短暂卡住所有 I/O;应改用定向清理:sync && echo 1 > /proc/sys/vm/drop_caches(只清 page cache,不影响 dentries/inodes)
- 更稳妥的做法是加定时任务,每天低峰期执行一次:
0 3 <em> </em> * sync && echo 1 > /proc/sys/vm/drop_caches 2>/dev/null
- 注意:此操作对主库无效,也不解决根本问题,但它能快速释放被“冻结”的内存,给调参争取观察窗口——很多所谓“调参无效”的案例,其实是没清缓存就急着验证
top 的 %MEM,Oracle 进程的 PGA 是私有内存,ps aux --sort=-%mem 看不到真实压力点ALTER DATABASE RECOVER MANAGED STANDBY DATABASE 能启动 MRP,但不等于它能持续运行——内存不足时它会反复中断重连,日志里留下大量 Media Recovery Waiting for thread 循环-
SGA_TARGET建议设为物理内存的 30%~40%,上限不超过 50%;若备库还承担只读报表负载,可上浮至 45%,但必须预留至少 2GB 给 OS 缓存和 Oracle 后台进程 -
PGA_AGGREGATE_TARGET建议设为 SGA_TARGET 的 30%~50%,且绝对值不低于 2GB(小内存服务器除外);因为 MRP 进程 apply 大事务时,排序/哈希操作全靠 PGA,设太小会导致频繁磁盘临时段写入,拖垮 apply 速度 - 必须禁用
MEMORY_TARGET—— 它会让 Oracle 自动在 SGA/PGA 间挪内存,而 ADG 的 apply 流程对 PGA 稳定性极度敏感,自动调整反而引发抖动
怎么验证当前设置是否真起效了
改完参数不是重启数据库就完事。ADG 备库的内存组件是动态生效的,但 MRP 进程不会自动 reload,得手动干预才能让新 PGA 分配策略覆盖正在运行的 apply 进程。
- 先确认参数已持久化:
SHOW PARAMETER sga_target 和 SHOW PARAMETER pga_aggregate_target
- 再检查实际分配:
SELECT component, current_size/1024/1024 MB FROM v$memory_dynamic_components WHERE component IN ('SGA Target', 'PGA Aggregate Target');
- 最关键一步:停掉并重启 MRP:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; → ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
(这会杀死旧 MRP 并拉起新进程,新进程才会按更新后的 PGA 设置初始化私有内存)
- 观察 5 分钟内
gv$managed_standby 的 status 是否稳定在 APPLYING_LOG,且 block# 持续递增
为什么清理 OS 缓存有时比调参数还管用
Oracle 在 ADG 备库上 apply redo 时,会高频访问数据文件块,这些块被 Linux page cache 缓存后,如果长时间没被换出,就会挤占本该留给 Oracle 进程的可用内存。尤其当备库同时跑着 BI 查询,OS 缓存可能吃掉 30%+ 物理内存,而 free -h 却显示 “available” 数值尚可——这是假象。
- 不要用
echo 3 > /proc/sys/vm/drop_caches 在生产环境乱清,它会短暂卡住所有 I/O;应改用定向清理:sync && echo 1 > /proc/sys/vm/drop_caches(只清 page cache,不影响 dentries/inodes)
- 更稳妥的做法是加定时任务,每天低峰期执行一次:
0 3 <em> </em> * sync && echo 1 > /proc/sys/vm/drop_caches 2>/dev/null
- 注意:此操作对主库无效,也不解决根本问题,但它能快速释放被“冻结”的内存,给调参争取观察窗口——很多所谓“调参无效”的案例,其实是没清缓存就急着验证
SHOW PARAMETER sga_target 和 SHOW PARAMETER pga_aggregate_target
SELECT component, current_size/1024/1024 MB FROM v$memory_dynamic_components WHERE component IN ('SGA Target', 'PGA Aggregate Target');
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; → ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;(这会杀死旧 MRP 并拉起新进程,新进程才会按更新后的 PGA 设置初始化私有内存)
gv$managed_standby 的 status 是否稳定在 APPLYING_LOG,且 block# 持续递增free -h 却显示 “available” 数值尚可——这是假象。
- 不要用
echo 3 > /proc/sys/vm/drop_caches在生产环境乱清,它会短暂卡住所有 I/O;应改用定向清理:sync && echo 1 > /proc/sys/vm/drop_caches(只清 page cache,不影响 dentries/inodes) - 更稳妥的做法是加定时任务,每天低峰期执行一次:
0 3 <em> </em> * sync && echo 1 > /proc/sys/vm/drop_caches 2>/dev/null - 注意:此操作对主库无效,也不解决根本问题,但它能快速释放被“冻结”的内存,给调参争取观察窗口——很多所谓“调参无效”的案例,其实是没清缓存就急着验证
ADG 备库的内存瓶颈从来不在理论计算,而在 apply 进程与 OS 缓存、后台进程、只读负载三者的资源争抢。参数调得再准,不清缓存就验证,等于蒙眼调弦。










