Buffer Exterminate是SGA动态收缩时的正常等待事件,发生在buffer cache granule被释放而会话正访问其内数据块时;需检查v$sga_current_resize_ops等视图确认shrink操作,并考虑禁用ASMM或设置组件最小值。
buffer exterminate 等待事件不是故障,而是 sga 动态收缩时的正常竞争现象;但它高频出现,说明当前 sga 自动管理正在频繁“拆东墙补西墙”,必须干预。
buffer exterminate 是什么,为什么它总在 shrink 时发生
这个等待事件只在 SGA_TARGET 启用且 Oracle 正在动态缩小某个组件(尤其是 Database Buffer Cache)时触发。本质是:某会话正要访问一个数据块,而该块所在的 buffer granule 刚好被选中释放——Oracle 必须先完成释放流程(从 hash chain / LRU chain 移除、清空状态),再让会话重载该块到剩余 granule 中。
它不表示损坏,但暴露了内存压力:系统在“边用边收”,说明当前 SGA_TARGET 设置偏高,或负载波动剧烈导致 Oracle 被迫反复调整。
- 只出现在
ALTER SYSTEM SET sga_target = ...或自动内存管理(ASMM)启用后 - 不会在
SGA_MAX_SIZE固定、且未启用自动调整时出现 - 和
physical reads高不同,它不增加 I/O,但会拖慢单个逻辑读的响应时间
如何确认是不是 SGA 动态调整惹的祸
别猜,直接查 Oracle 的“内存操作日志”视图:
运行以下查询,重点看是否有近期 shrink 操作:
SELECT operation, component, initial_size/1024/1024 init_mb,
target_size/1024/1024 target_mb, status, start_time, end_time
FROM v$sga_current_resize_ops
WHERE operation = 'SHRINK';再查历史汇总:
SELECT component, oper_type, COUNT(*) cnt,
MIN(start_time) first_op, MAX(end_time) last_op
FROM v$sga_dynamic_components
WHERE current_size < min_size -- 表明曾被压到最小值以下又恢复
GROUP BY component, oper_type;- 如果
v$sga_current_resize_ops返回非空结果,尤其component = 'DEFAULT buffer cache',基本坐实 - 如果
v$sga_dynamic_free_memory显示可用 free memory < 100MB,说明 SGA 几乎没冗余空间,收缩极易发生 - 注意:
buffer exterminate不会出现在 AWR 报告的 Top 5 Events 默认页,需手动在 “Wait Events” 部分搜索
怎么停掉这种“边跑边拆”的行为
核心思路是切断自动收缩的触发条件,而不是禁用整个 ASMM。有三类实操路径:
- 设下底线:对关键组件显式设置最小值,比如
ALTER SYSTEM SET db_cache_size = 4G SCOPE=BOTH;—— 这会锁定缓冲区下限,Oracle 就不敢再把它 shrink 到 4G 以下 - 收窄弹性区间:把
sga_target调低(如从 12G → 8G),同时保持sga_max_size不变(如仍为 16G),给 Oracle 更少“腾挪空间”,减少无谓调整 - 彻底关闭 ASMM(仅限明确知道各组件配比的场景):执行
ALTER SYSTEM SET sga_target = 0 SCOPE=SPFILE;,然后重启;之后手动设置db_cache_size、shared_pool_size等
注意:sga_target = 0 不等于关闭所有内存管理,只是退回到手工模式;pga_aggregate_target 仍可独立启用自动 PGA 管理。
调完之后必须验证的两件事
改参数不是终点,得看效果是否落地:
- 检查
v$sga_dynamic_components中各组件的min_size是否已生效(尤其你手动设过的那个),且current_size不再围绕min_size上下剧烈跳动 - 持续监控 15 分钟内
v$session_event或 AWR,确认buffer exterminate的 waits/sec 归零或降至个位数;若仍有,说明还有其他组件(如shared_pool)在被 shrink,需同法处理
最容易被忽略的是:即使你设了 db_cache_size,如果 sga_target 仍远高于各组件 min_size 之和,Oracle 仍可能把多余内存分配给其他组件并随后 shrink 它们——所以必须同步压低 sga_target,让它贴近实际所需总和。


















