AWR的Advisory建议不可直接采纳,尤其Buffer Pool与Shared Pool推荐冲突时会引发SGA内存抖动;应通过“SGA Resize Operations”小节、V$SGA_DYNAMIC_COMPONENTS、V$SGAINFO及V$PGA_TARGET_ADVICE等动态视图定位真实瓶颈,并满足/dev/shm大小、SGA子参数清零、workarea_size_policy=AUTO三条件方可生效。
awr 的 advisory 建议不能直接照搬,尤其当 buffer pool 和 shared pool 的推荐方向冲突时,强行按建议调参反而会触发 sga 内存抖动。
查 AWR 里 “SGA Resize Operations” 小节识别真实抖动源头
这个小节不是装饰,是 ASMM 实际执行过的 resize 操作流水账。重点看三列:
-
Component列:如果shared pool和DEFAULT buffer cache频繁交替SHRINK/GROW,说明内存在反向挤压,不是某组件“不够”,而是 ASMM 在失衡状态下反复救火 -
Time列:若操作集中在整点(如 10:00、11:00),大概率是定时 job(统计信息收集、报表生成)引发瞬时解析压力,该调的是 job 调度或 SQL 写法,不是无脑扩 shared pool -
Duration (ms)列:单次 > 500ms 的 resize 往往伴随latch: shared pool或library cache lock上升,说明调整动作本身已成瓶颈,此时扩内存只会加重争用
用 V$SGA_DYNAMIC_COMPONENTS 验证当前是否真在“挣扎”
别只看 AWR 报告里静态的 advisory 数值,先确认实例当前状态是否稳定:
-
OPER_COUNT> 50 且LAST_OPER_TIME在最近 60 分钟内 → ASMM 正高频干预,不是配置问题,是内存分配逻辑被卡住 -
CURRENT_SIZE接近MIN_SIZE但远小于MAX_SIZE→ Oracle 想扩但扩不出去,常见原因是SGA_TARGET已到顶,或Granule Size碎片化导致无法凑出连续块 -
LAST_OPER_TYPE='SHRINK'且OPER_MODE='AUTO'→ 某组件(通常是 shared pool)正被 buffer cache 反向挤占,根源常是硬解析风暴或未绑定变量
交叉核对 V$SGAINFO 和 V$PGA_TARGET_ADVICE 避免粒度错配
Oracle 分配 SGA 按 granule(典型 4MB 或 16MB),PGA 则按 workarea 动态切分。二者不能混用一套逻辑:
- 查
V$SGAINFO中Granule Size值,再检查V$SGA_DYNAMIC_COMPONENTS里各CURRENT_SIZE是否为其整数倍 —— 不是,说明实际生效大小已被向下取整,剩余空间闲置,扩参无效 -
V$PGA_TARGET_ADVICE的建议只反映排序类操作历史,sorts (disk)/sorts (memory) > 5%才需调PGA_AGGREGATE_TARGET;若临时表空间暴增但该比值正常,可能是HASH JOIN回退磁盘,得查v$sql_workarea而非盲目扩 PGA - 设了
MEMORY_TARGET后,SGA_TARGET和PGA_AGGREGATE_TARGET会被忽略 —— 这个细节常被漏掉,导致调了参数却没生效
真正起效前必须确认的三个硬条件
哪怕 AWR 建议调大 2GB,没满足这三条,调了也白调:
-
/dev/shm大小 ≥MEMORY_MAX_TARGET:Linux 下ORA-00845就是它报的,df -k /dev/shm必须先看 - 所有 SGA 子组件参数(
db_cache_size、shared_pool_size等)必须为 0 或未设置:只要显式设过非零值,ASMM 就被锁死,SGA_TARGET只能往上加,不能动态重分配 -
workarea_size_policy必须为AUTO:手动设sort_area_size会失效,且破坏 Oracle 对哈希/位图等多类 workarea 的统一调度
复杂点在于:AWR 的 advisory 是基于过去负载的统计拟合,而内存抖动是实时资源争用的结果。两者不一致时,以 V$SGA_DYNAMIC_COMPONENTS 的 OPER_COUNT 和 V$PGA_TARGET_ADVICE 的 estd_overalloc_count 为准 —— 它们反映的是 Oracle 当下“想做什么”,而不是“曾经做过什么”。


















