查v$sga_dynamic_components可实时查看SGA各组件当前内存分配情况,但仅为瞬时快照;需结合dba_hist_memory_resize_ops回溯历史调整、v$sgastat定位shared pool内部热点,并用AWR报告交叉验证趋势。
查v$sga_dynamic_components看实时SGA组件浮动情况
sga不是静态的,尤其启用了sga_target后,oracle会在db_cache_size、shared_pool_size等组件间动态重分配内存。直接查v$sga_dynamic_components能看清当前各组件实际占多少——注意它只反映“当前快照”,不带时间维度。
常见错误是把current_size当固定值去比对参数文件,其实它可能刚被自动收缩过。比如shared_pool_size设了2G,但v$sga_dynamic_components里显示只有1.6G,说明Oracle因buffer cache压力大,临时挪走了400MB。
- 加
WHERE last_oper_type IN ('GROW', 'SHRINK')可过滤出最近被调整过的组件 - 对比
min_size和current_size:若差值持续扩大,说明该组件长期处于“被挤压”状态(如shared pool长期低于设定下限) -
oper_mode = 'MANUAL'表示该组件被手动锁定,不再参与自动调节,容易导致其他组件失衡
用dba_hist_memory_resize_ops回溯历史内存伸缩动作
这个视图才是AWR里真正记录SGA增长脉络的地方,每条记录对应一次内存组件大小变更,含起止时间、操作类型、旧值/新值。
典型场景:某天凌晨3:20 shared pool突然从1.8G涨到2.5G,你得立刻查这个时间点前后的dba_hist_memory_resize_ops,确认是Oracle自动扩的,还是DBA手工执行了ALTER SYSTEM SET shared_pool_size=2.5G。
- 查询时务必加时间过滤:
WHERE start_time >= TO_DATE('2026-04-10 00:00:00', 'YYYY-MM-DD HH24:MI:SS'),避免默认只查最近7天(该视图保留期通常为7天) - 关注
component列是否为shared pool或large pool——buffer cache极少主动收缩,但shared pool会因SQL版本爆炸频繁伸缩 -
status = 'COMPLETE'才代表操作真正落地;'PENDING'说明当时有锁冲突,后续可能被回滚
结合v$sgastat定位shared pool内部热点
光知道shared pool涨了没用,得知道它被谁吃掉了。这时v$sgastat比v$sga_dynamic_components更细:它能拆到子池(pool)、对象类型(name)级别。
比如发现shared pool在2小时内从1.2G涨到1.9G,但v$sga_dynamic_components只显示总量变化,而v$sgastat能告诉你:其中sql area占了600MB,library cache占了320MB,free memory只剩23MB——这基本锁定是硬解析风暴或未绑定变量SQL泛滥。
- 重点过滤:
WHERE pool = 'shared pool' AND bytes > 1024*1024(排除小碎片干扰) -
name = 'free memory'持续低于50MB,shared pool就已濒临OOM,ORA-04031风险极高 - 若
name列出现大量kglsim heap或row cache objects,说明可能是字典缓存争用或模拟器泄漏
用AWR报告里的“SGA Memory Summary”交叉验证趋势
单点数据易误判,AWR报告的“SGA Memory Summary”页把多个快照串成线,能看出增长是否线性、是否伴随业务高峰、是否突兀跳变。
注意它不展示组件明细,只给总SGA、buffer cache、shared pool三类粗粒度汇总。所以必须和前面三个视图联动:比如AWR里看到shared pool在14:00–15:00陡增,就去dba_hist_memory_resize_ops查具体操作,再用v$sgastat抓那个时刻的内存分布。
- 报告中“Buffer Cache Size”和“Shared Pool Size”的数值来自
v$sga_dynamic_components快照,但单位是MB且四舍五入,精度不如视图 - 若AWR里“SGA Resize Operations”部分为空,不代表没发生伸缩——可能因
STATISTICS_LEVEL = BASIC关闭了统计收集 - 跨报告对比时,注意不同报告的采样间隔是否一致(默认60分钟),否则斜率会失真
最麻烦的是增长原因藏在SQL层面:比如某条未绑定变量的报表SQL被反复执行,每次生成新子游标,v$sgastat里sql area持续膨胀,但dba_hist_memory_resize_ops只记了一次shared pool扩容。这种时候必须顺藤摸瓜查v$sqlarea的version_count和sharable_mem,否则永远只能看见症状,找不到病灶。











