streams池在amm/asmm下被强制收缩导致内存不足,是“streams aq: enqueue blocked on low memory”的根本原因;需检查v$memory_dynamic_components中current_size是否远小于min_size且后者极小,以及v$parameter中streams_pool_size是否为0,结合awr中streams pool hit%
直接结论:streams池在amm/asmm下持续收缩,是导致streams aq: enqueue blocked on low memory等待的根本原因,不是配置太小,而是内存被强制挪走。
查Streams池是否正在收缩
这个状态决定了你该不该动参数——如果它卡在“收缩中”,调大streams_pool_size基本无效。
- 执行
SELECT component, current_size, min_size, max_size FROM v$memory_dynamic_components WHERE component = 'streams pool'; - 重点看
current_size是否远小于min_size,且min_size本身很小(比如 0 或几 MB) - 更关键的是运行
SELECT value FROM v$parameter WHERE name = 'streams_pool_size';,如果返回0,说明Oracle正按需动态分配,但实际已被挤占 - 此时
V$SGASTAT里streams pool的free memory可能极低,而buffer cache却在高位波动
禁用自动收缩的两种方式
Oracle 11.2.0.4 的 Bug(27634991)让streams pool在 ASMM 下无法稳定驻留。必须打破“自动管理”假象。
- 方案一(推荐):关闭 ASMM,手动固定
streams_pool_size
— 设置sga_target=0,再设streams_pool_size=256M(根据导出并发量调整,小库 128M 起步)
— 同时确保shared_pool_size和db_cache_size也显式指定,避免隐式挤压 - 方案二:保留 ASMM,但用
_kghdsidx_count绕过收缩逻辑(隐含参数,需测试)
— 在 pfile/spfile 中加_kghdsidx_count=1,重启生效
— 注意:该参数在 11.2.0.4 后补丁中已部分修复,但未彻底,仍需验证
AWR中确认内存分布是否失衡
别只盯Top 5 Timed Events,要从Instance Efficiency Percentages和Memory Statistics交叉判断。
- 在 AWR 报告里定位“Memory Statistics”部分,检查
Streams Pool Hit %是否低于 85%,低于 70% 基本确认饥饿 - 看“Buffer Pool Statistics”,如果
db_cache_size使用率长期 >95%,而streams pool使用率 - 运行
SELECT * FROM dba_hist_memory_resize_ops WHERE end_time > SYSDATE-1 ORDER BY end_time DESC;,若看到大量streams pool的SHRINK操作,且status为COMPLETE,就坐实了 Bug 触发 - 注意:
awr_report_text默认不显示 streams pool 细节,要用awr_report_html或查询dba_hist_sgastat补全
真正麻烦的不是改参数,而是改完后要验证expdp或impdp初始化阶段是否还卡在Streams AQ: enqueue blocked on low memory——这个等待一旦消失,后续步骤才会真正开始跑。很多 DBA 改完就以为好了,结果第一次导出还是等 90 秒,其实是没等够时间看效果。











