os thread startup等待事件本质是Oracle向OS申请线程时OS响应迟缓,属操作系统瓶颈而非数据库内部问题;需通过预设parallel_min_servers、清理残留并行对象、禁用自动并行策略及验证OS资源(如pid_max、ulimit、大页)来根治,而非调大parallel_max_servers。
“os thread startup”不是数据库内部瓶颈,而是操作系统层面进程创建受阻的信号——直接调大 parallel_max_servers 只会让问题更糟,真正该做的是预分配 + 限制并行源头。
为什么 os thread startup 等待时间会暴涨
这个等待事件本质是 Oracle 向 OS fork 新线程(比如并行 slave)时,OS 响应变慢。正常情况单次耗时应
- Linux 的
/proc/sys/kernel/pid_max接近上限,或ulimit -u(用户进程数限制)被压穿 - 系统内存紧张,导致 fork 失败后重试或延迟(尤其开启大页但未配足)
- 高并发
CREATE INDEX PARALLEL或物化视图刷新,slave 按串行方式逐个启动(512 个 slave = 512 次 fork) - RAC 环境下节点间资源争用放大 OS 层延迟
设置 parallel_min_servers 预热进程池
避免运行时临时 fork,把 slave 进程提前拉起来。关键不是“够不够”,而是“稳不稳定”:
- 查当前最大并发需求:
SELECT MAX(DEGREE) FROM DBA_INDEXES WHERE DEGREE > 1,或看历史 ASH 中PX COORDINATOR最高并发数 - 设
parallel_min_servers为该值的 1.2–1.5 倍(例如最高需 64,则设 80),写进 pfile/spfile:ALTER SYSTEM SET parallel_min_servers=80 SCOPE=BOTH; - 注意:该参数只对新连接生效,重启实例才能确保全部预热;若用 RAC,每个 instance 都要单独设
- 别碰
parallel_max_servers—— 它只是上限,不解决冷启动延迟,反而可能触发 PGA 爆炸和PX Deq Credit: need buffer
从源头掐断意外并行
很多 os thread startup 根本不是业务主动发起的,而是索引残留并行度或优化器自作主张:
- 立刻清理所有残留并行对象:
SELECT 'ALTER INDEX '||owner||'.'||index_name||' NOPARALLEL;' FROM DBA_INDEXES WHERE DEGREE > 1; - 禁用自动并行决策(Oracle 11g+):
ALTER SYSTEM SET parallel_degree_policy = 'MANUAL'; - 检查是否误开隐含参数如
_optimizer_adaptive_plans(11g 默认关,但补丁后可能开),它会在运行时动态加并行 - OLTP 系统中,
ALTER SESSION ENABLE PARALLEL DML;必须显式执行,不能依赖默认行为
验证 OS 层是否真的扛得住
数据库调参前,先确认 OS 没被拖垮:
- 查 fork 延迟:
dmesg | grep -i "out of memory\|fork",有 OOM killer 日志就危险了 - 看当前进程负载:
ps -eLf | wc -l对比cat /proc/sys/kernel/pid_max,若超过 70%,必须调大 pid_max - 检查 ulimit:
su - oracle -c 'ulimit -u',生产环境建议 ≥ 16384;若为 soft limit,需同步改 hard limit - 确认大页配置正确:
grep HugePages_ /proc/meminfo,若HugePages_Free长期为 0,说明分配失败,parallel_min_servers预热会失败
最常被忽略的一点:RAC 环境下,os thread startup 往往是某个节点先卡住,然后通过 DFS lock handle 和 gc cr request 把压力传导到其他节点——所以监控不能只盯单实例 ASH,得看集群级 AWR 中 “Top 5 Timed Foreground Events” 是否跨节点同步出现该等待。


















