ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ORA-00020: maximum number of processes (150) exceeded 的解决方法:从 processes 参数到连接池配置的完整排查

ORA-00020: maximum number of processes (150) exceeded 的解决方法:从 processes 参数到连接池配置的完整排查 1. 现场长什么样ORA-00020 到底在报什么ORA-00020: maximum number of processes (150) exceeded直译过来就是「进程数超过上限 150」。它和 ORA-01000游标超限经常被混为一谈但两者卡的位置完全不同ORA-01000 卡的是单个会话里打开的游标数量ORA-00020 卡的是整个数据库实例能同时容纳的进程总数。一旦触顶新的连接请求会被直接拒绝报错信息里通常还会带一句ORA-00020: maximum number of processes (150) exceeded业务侧表现为「连不上库」「连接池疯狂报错」「应用启动失败」。这个报错适合谁看DBA 要定位是哪个环节把进程吃满了后端开发要确认自己的连接池配置有没有泄漏运维要判断是调参数还是改代码。150 这个数字很典型是 Oracle 早期版本或测试环境的默认值生产环境如果没动过processes参数很容易在并发上来之后撞墙。需要先建立一个认知processes是实例级硬上限sessions是会话级上限两者有换算关系。Oracle 官方文档里sessions默认约等于(1.1 * processes) 5。也就是说进程耗尽的根因往往不是「用户真的开了 150 个连接」而是后台进程、并行查询进程、连接池空闲连接、泄漏连接叠加在一起把额度吃光了。所以排查顺序应该是先看当前进程占用分布再看参数最后才决定是调参数还是修连接池。我试过在一个压测环境里应用只配了 20 个连接但processes还是被打满最后发现是并行查询PX进程和一批没释放的 JDBC 连接共同造成的。所以别一上来就ALTER SYSTEM SET processes1000那只是把问题往后推。2. 前置准备用 TaoToken 打通排查链路排查这类问题很多时候需要一边查文档、一边让模型帮你分析 SQL 输出、一边生成连接池配置骨架。我习惯用 TaoToken 来做这件事它把模型对话、API 调用、Coding Plan 放在一个控制台里省得在多个工具之间来回切。如果你只是想快速问「ORA-00020 的 processes 和 sessions 怎么换算」直接进模型对话就行把报错原文贴进去让它给出排查思路。如果你要写脚本自动采集v$process、v$session的数据那就需要 API Key走 API 接入的方式把采集逻辑和模型分析串起来。长期做数据库运维或写 Agent 的话Coding Plan 更合适额度稳定适合反复调试。具体入口我列一下方便你按需选模型对话问排查思路、贴报错分析https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteCoding Plan长期编码、写运维脚本、Agenthttps://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite控制台管理额度、看调用https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteAPI Keys生成密钥接入脚本https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入文档看接口格式、参数https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite注意TaoToken 是模型调用与开发辅助平台不是数据库代理也不做任何网络中转。数据库连接问题必须在数据库侧和连接池侧解决模型只帮你分析和生成代码。拿到 Key 之后你可以把下面这段排查 SQL 的输出丢给模型让它帮你判断是哪个进程类型占了大头。这一步不涉及任何敏感操作纯粹是文本分析。3. 可复制配置从 processes 参数到 HikariCP3.1 查询当前进程与会话占用先用 DBA 账号连上库执行下面这组 SQL。注意v$resource_limit能看到当前值和上限v$process能按类型分组。-- 查看 processes / sessions 当前值与上限 SELECT resource_name, current_utilization, max_utilization, limit_value FROM v$resource_limit WHERE resource_name IN (processes, sessions); -- 按进程类型统计占用找出谁在吃额度 SELECT p.type, COUNT(*) AS cnt FROM v$process p GROUP BY p.type ORDER BY cnt DESC; -- 查看当前会话数与活跃会话 SELECT status, COUNT(*) FROM v$session GROUP BY status; -- 查看是否有大量 INACTIVE 连接长期不释放 SELECT machine, program, COUNT(*) AS conn_cnt FROM v$session WHERE type USER GROUP BY machine, program ORDER BY conn_cnt DESC;如果v$process里USER类型占比很高说明是应用连接池的问题如果BACKGROUND或并行相关类型占比高那要去看并行度和后台进程配置。3.2 调整 processes 与 sessions 参数确认是额度不够之后再动参数。processes是静态参数改完必须重启实例才生效sessions可以动态调整但通常跟着processes一起改。-- 查看当前 spfile 位置确认是 spfile 还是 pfile SHOW PARAMETER spfile; -- 调整 processes静态参数需重启 ALTER SYSTEM SET processes 500 SCOPE SPFILE; -- 调整 sessions动态参数可立即生效 ALTER SYSTEM SET sessions 555 SCOPE BOTH; -- 如果用的是 pfile需要手动编辑文件后重启 -- 重启命令在操作系统层面执行 -- shutdown immediate; -- startup;注意processes调大之后操作系统层面的信号量、内存也会跟着增加别盲目设成几万。一般按「峰值连接数 × 1.5 后台进程余量」来估。改完记得SHOW PARAMETER processes确认并重启验证。3.3 HikariCP 连接池配置骨架参数调大只是兜底真正要治的是连接泄漏。下面是一个 HikariCP 的配置骨架重点在maximumPoolSize、leakDetectionThreshold和maxLifetime这三个。spring: datasource: hikari: # 池内最大连接数别超过 processes 的 70% maximum-pool-size: 50 # 最小空闲连接避免频繁创建销毁 minimum-idle: 10 # 连接超时拿不到连接就快速失败别无限等 connection-timeout: 30000 # 空闲连接超时及时回收 idle-timeout: 600000 # 连接最大存活时间比数据库侧超时略小 max-lifetime: 1800000 # 泄漏检测超过 60 秒没归还就打印堆栈 leak-detection-threshold: 60000 # 连接测试查询 connection-test-query: SELECT 1 FROM DUAL对应的 Java 配置类写法Configuration public class HikariConfig { Bean public DataSource dataSource() { HikariDataSource ds new HikariDataSource(); ds.setJdbcUrl(jdbc:oracle:thin://host:1521/ORCLPDB1); ds.setUsername(app_user); ds.setPassword(your_password); ds.setMaximumPoolSize(50); ds.setMinimumIdle(10); ds.setConnectionTimeout(30000); ds.setIdleTimeout(600000); ds.setMaxLifetime(1800000); ds.setLeakDetectionThreshold(60000); ds.setConnectionTestQuery(SELECT 1 FROM DUAL); return ds; } }leakDetectionThreshold是关键它会在连接被借出超过阈值还没归还时打印堆栈直接告诉你哪段代码忘了close()。很多 ORA-00020 的根因就是这里暴露出来的。4. 验证请求确认进程数回落且业务恢复改完参数、重启实例、调整连接池之后要有一套验证动作别改完就不管了。第一步重启后确认参数生效SHOW PARAMETER processes; SHOW PARAMETER sessions; SELECT resource_name, current_utilization, limit_value FROM v$resource_limit WHERE resource_name IN (processes, sessions);第二步观察一段时间内的进程数变化确认没有持续上涨-- 每隔几秒执行一次看 current_utilization 是否稳定 SELECT resource_name, current_utilization, max_utilization FROM v$resource_limit WHERE resource_name processes;第三步从应用侧发起一次真实请求确认连接能正常获取和归还。如果你用 TaoToken 的模型对话生成了压测脚本可以直接跑一轮观察v$session里USER类型的连接数是否在请求结束后回落。第四步配置监控告警。下面是一个简单的告警阈值思路可以用脚本定时采集-- 当进程使用率超过 80% 时触发告警 SELECT resource_name, current_utilization, limit_value, ROUND(current_utilization / limit_value * 100, 2) AS usage_pct FROM v$resource_limit WHERE resource_name processes AND current_utilization / limit_value 0.8;把这条 SQL 的输出接到你的监控系统里超过 80% 就发通知别等到 100% 报错才动手。5. 本篇常见错排查错误一只调 processes 不查泄漏。这是最常见的坑。把 150 调到 1000短期内不报错了但连接泄漏还在过几天又打满。正确做法是先用leakDetectionThreshold找出泄漏点再决定要不要调参数。错误二把 ORA-00020 和 ORA-01000 搞混。前者是进程总数超限后者是单会话游标超限。ORA-01000 的排查重点是open_cursors和 Statement 是否关闭ORA-00020 的重点是连接池和进程总数。两者排查路径不同别用错方向。错误三sessions 调了但 processes 没调。sessions依赖processes如果processes还是 150sessions设再大也没用因为底层进程额度没放开。两个要一起看。错误四连接池 maximumPoolSize 设得比 processes 还大。比如 processes 是 150连接池配了 200那必然有 50 个连接拿不到进程额度直接报 ORA-00020。池大小要留出后台进程和并行查询的余量一般不超过 processes 的 70%。错误五忘了关 ResultSet 和 Statement。虽然 ORA-00020 主要卡进程但游标泄漏会间接导致连接无法归还最终也会推高进程占用。养成在finally块里关闭资源的习惯或者用 try-with-resources。// 推荐写法try-with-resources 自动关闭 try (Connection conn dataSource.getConnection(); PreparedStatement ps conn.prepareStatement(SELECT * FROM orders WHERE id ?)) { ps.setLong(1, orderId); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { // 处理结果 } } } catch (SQLException e) { log.error(query failed, e); }错误六重启后没验证就收工。processes是静态参数改完不重启等于没改。重启后一定要用SHOW PARAMETER和v$resource_limit双重确认再看业务是否恢复。6. 后续怎么接把排查能力沉淀下来这套流程跑通之后建议把采集 SQL 和告警逻辑固化成一个脚本定期跑别每次出事再手忙脚乱。如果你要写自动化运维脚本或者做一个能自动分析v$process输出的 Agent可以用 TaoToken 的 Coding Plan 来承接额度稳定适合反复调试。需要生成 API Key 接入脚本的走这个入口https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入文档在这里接口格式和参数都写清楚了https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite如果你只是想快速问一个排查思路比如「v$process 里 USER 类型占比 90% 怎么处理」直接进模型对话贴数据就行https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite最后留一个实操建议把v$resource_limit的查询做成定时任务每 5 分钟采一次存到监控表里。这样下次再出 ORA-00020你手里有历史曲线能直接看出是突增还是缓慢泄漏定位速度快很多。参数调整只是止血连接池治理和监控才是长期方案。
返回列表