如何处理Data Guard备库内存耗尽_Active Data Guard环境下的SGA与PGA优化

2次阅读

备库内存耗尽的典型表现是mrp0进程卡在wait_for_log或applying_log且sequence#停滞,v$sgastat中free memory趋零,sga/pga使用率超95%,并可能触发ora-04030或oom killer杀进程。

备库内存耗尽的典型表现是什么 Active Data Guard 备库一旦内存不足,最直接的信号不是报错,而是同步进程卡住或变慢——MRP0 进程状态长期为 WAIT_FOR_LOGAPPLYING_LOGsequence# 不再推进;同时 v$sgastatfree memory 接近零,gv$memory_dynamic_components 显示 SGA_TARGETPGA_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_targetSHOW 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_standbystatus 是否稳定在 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
  • 注意:此操作对主库无效,也不解决根本问题,但它能快速释放被“冻结”的内存,给调参争取观察窗口——很多所谓“调参无效”的案例,其实是没清缓存就急着验证

ADG 备库的内存瓶颈从来不在理论计算,而在 apply 进程与 OS 缓存、后台进程、只读负载三者的资源争抢。参数调得再准,不清缓存就验证,等于蒙眼调弦。

text=ZqhQzanResources