Latch Sleep次数高但Spin Gets也高,说明存在竞争但线程靠CPU自旋缓解了部分压力;需结合Sleep比例、平均睡眠时间及具体latch类型综合判断争用严重性。
Latch Sleep 次数高但 Spin Gets 也高,说明什么?
这通常不是严重争用,而是 latch 设计本就依赖自旋(spin)来避免立即睡眠。oracle 在获取 latch 失败时,会先 spin 若干次(由 _latch_spin_count 控制,默认 2000),失败后才进入 sleep。所以高 spin gets + 高 sleeps 往往意味着:竞争确实存在,但线程没直接挂起,靠 cpu 轮询扛住了部分压力。
关键看比例:Sleeps / (Gets + Misses) > 5% 才值得深挖;若 Spin Gets / Misses 接近 1:1,说明 spin 基本都“白转”了——CPU 空耗,但没抢到 latch,这时 sleep 是必然结果。
- 查 AWR 报告里 “Latch Sleep Breakdown” 表,重点关注
% Sleep Time和Avg Sleep ms,>10ms 就算异常 -
latch free等待事件的waits数量要和该 latch 的Sleeps对得上,否则可能是其他 latch 干扰 - 别只盯总 sleep 次数——
immediate gets高而misses低,说明大部分请求根本没触发 spin/sleep 流程
如何定位具体是哪个 latch 在 Sleep?
AWR 中 “Latch Activity” 表按 latch name 统计,但默认只列 top N(如 20)。真正问题 latch 可能被截断。必须查底层视图 DBA_HIST_LATCH 或实时 V$LATCH,按 SLEEPS 列倒序。
常见高 sleep latch 有:cache buffers chains(热块)、library cache(硬解析/共享池碎片)、shared pool(内存分配)、row cache objects(字典缓存争用)。它们的 sleep 特征不同:
-
cache buffers chains:sleep 次数常伴随高db file sequential read或buffer busy waits -
library cache:sleep 同时parse time elapsed上升,SQL 硬解析多或 shared_pool_size 不足 -
shared pool:sleep 高且free memory在V$SGASTAT中持续低于 5MB,说明内存紧张
Spin count 调大一定能减少 Sleep 吗?
不能。盲目调高 _latch_spin_count 只会让 CPU 更忙,可能拉高 %User Time,甚至引发 OS 调度延迟,反而延长实际响应时间。Oracle 11g+ 默认已设为 2000,对多数系统足够。
是否该调,取决于实测:开 AWR 或 ASH 抓 10 分钟,对比调参前后 latch free 等待时间、CPU 使用率、TPS。如果 sleep 次数降了但 CPU 升了 15%,且业务响应没变快,就是负优化。
- 仅在确认是 latch 自旋不足(即 spin 失败率极高、sleep 时间又极短<1ms)时才考虑微调
- 生产环境禁止直接改隐含参数,应通过
ALTER SYSTEM SET "_latch_spin_count"=3000 SCOPE=SPFILE并重启 - 更稳妥的解法通常是优化 SQL(减少逻辑读)、调整对象设计(如 hash 分区缓解 CBC)、或增大相关池大小
为什么有些 latch Sleep 时间极短却频繁发生?
典型如 redo allocation 或 redo writing latch,在高并发 insert/update 场景下,每个事务都要快速申请 redo 相关 latch。它 sleep 时间可能只有 0.1ms,但每秒上千次,累积等待显著。
这种“高频低延时”sleep 容易被忽略,但它反映的是系统吞吐瓶颈——不是 latch 本身慢,而是单位时间 latch 请求量过大。此时看 V$LATCH_CHILDREN,若 child latch 分布严重不均(比如 1 个 child 占 90% sleeps),说明 latch 拆分粒度不够,需检查是否启用了 _use_single_log_writer 或 log_parallelism 设置不合理。
- 用
SELECT name, child#, sleeps FROM V$LATCH_CHILDREN WHERE name = 'redo allocation' ORDER BY sleeps DESC查倾斜 - 12c+ 可启用
ENABLE PL/SQL日志写入并行化(需设置LOG_PARALLELISM≥ 2) - 检查是否有大量小事务提交——合并为批量操作比调 latch 参数更有效










