Oracle 19C大量非活跃会话问题排查与优化咨询
Oracle 19C 非活跃会话问题排查与优化
背景信息
我们的应用使用c3p0-0.9.5.5.jar和ojdbc8-12.2.0.1.jar连接Oracle 19C,当前c3p0配置参数如下:
com.mchange.v2.c3p0.PoolBackedDataSource@a07b9a4b [ connectionPoolDataSource ->com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@74b02295 [ acquireIncrement -> 1, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, identityToken -> 31qzq3ay1xf5c0jx94505|6f4d2294, idleConnectionTestPeriod -> 5, initialPoolSize -> 0, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 45, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 0, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@d898aa34 [ description -> null, driverClass -> null, factoryClassLocation -> null, forceUseNamedDriverClass -> false, identityToken -> 31qzq3ay1xf5c0jx94505|6d9428f3, jdbcUrl -> jdbc:oracle:thin:@x.x.x.x:1521:orcl, properties -> {user=******, password=******} ], preferredTestQuery -> null, privilegeSpawnedThreads -> false, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, extensions -> {}, factoryClassLocation -> null, identityToken -> 31qzq3ay1xf5c0jx94505|900649e, numHelperThreads -> 3 ]]
执行查询语句:
select status, program, username, last_call_et from v$session WHERE STATUS = 'INACTIVE';
查询结果示例:
| USERNAME | STATUS | PROGRAM | LAST_CALL_ET |
|---|---|---|---|
| EMPDB | INACTIVE | JDBC Thin Client | 1727905 |
| EMPDB | INACTIVE | JDBC Thin Client | 1727904 |
目前Oracle 19C中存在250余个非活跃会话,需解决以下问题:
- 非活跃会话是否会导致Oracle数据库服务器CPU飙升?
- 如何排查非活跃会话产生的根本原因?
- 是否可通过配置应用服务器属性缓解该问题?
问题解答
1. 非活跃会话是否会导致Oracle数据库服务器CPU飙升?
非活跃会话本身不会直接导致CPU飙升——这类会话处于空闲状态,没有执行任何SQL或数据库操作,不会占用CPU资源。但数量过多会带来间接影响:
- 占用数据库PGA内存资源,当内存不足时可能引发频繁内存交换(SWAP),间接推高CPU使用率。
- 过多会话会增加数据库进程/线程的管理开销,极端情况下可能拖慢数据库响应速度。
2. 如何排查非活跃会话产生的根本原因?
数据库端排查
- 追踪会话历史活动:执行以下SQL获取会话最后执行的语句、耗时等信息,判断是否是应用未正确释放连接:
SELECT s.sid, s.serial#, s.username, s.program, s.last_call_et, sql.sql_text, sql.elapsed_time FROM v$session s LEFT JOIN v$sql sql ON s.sql_id = sql.sql_id WHERE s.status = 'INACTIVE' AND s.username = 'EMPDB'; - 查看会话系统关联信息:通过
v$process关联会话对应的操作系统进程,确认是否是应用连接池未回收:SELECT s.sid, s.serial#, p.spid, s.machine, s.osuser, s.logon_time FROM v$session s JOIN v$process p ON s.paddr = p.addr WHERE s.status = 'INACTIVE' AND s.username = 'EMPDB'; - 检查数据库空闲超时配置:确认用户的
IDLE_TIME资源限制,若未配置,空闲会话会一直留存:SELECT profile, resource_name, limit FROM dba_profiles WHERE resource_name = 'IDLE_TIME' AND profile = (SELECT profile FROM dba_users WHERE username = 'EMPDB');
应用端排查
- 检查连接池配置逻辑:
当前c3p0配置maxPoolSize=10,但数据库出现250+会话,说明要么是多实例部署的连接池配置未统一,要么是代码存在连接未正确关闭(如Connection未在finally块释放)的问题。
建议开启连接泄漏追踪参数:c3p0.unreturnedConnectionTimeout=300 c3p0.debugUnreturnedConnectionStackTraces=true - 排查应用代码:
检查所有获取数据库连接的代码,确保Connection对象在try-with-resources或finally块中调用close();同时排查是否存在长事务未提交的情况,未提交的事务会导致会话处于INACTIVE但无法释放的状态。 - 核对线程池与连接池匹配度:若应用用多线程处理请求,需确保线程池大小不超过连接池
maxPoolSize,避免线程竞争连接导致连接无法及时回收。
3. 是否可通过配置应用服务器属性缓解该问题?
可以,通过调整c3p0连接池和应用服务器配置来缓解:
- 优化c3p0连接池配置:
- 设置
unreturnedConnectionTimeout=300:强制回收5分钟内未归还的连接,避免泄漏。 - 开启
debugUnreturnedConnectionStackTraces=true:打印连接泄漏的堆栈信息,定位代码问题。 - 调整
maxIdleTimeExcessConnections=10:让超过最小池大小的空闲连接更快回收。 - 启用
testConnectionOnCheckin=true并设置preferredTestQuery="SELECT 1 FROM DUAL":确保回收的连接有效,避免无效连接占用会话。
- 设置
- 调整应用服务器线程池:
统一多实例的连接池配置,确保总连接数不超过数据库processes参数限制;同时让应用服务器线程池大小匹配连接池maxPoolSize,避免线程竞争连接。 - 补充数据库端配置:
给EMPDB用户配置空闲超时,强制断开长时间空闲的会话:ALTER PROFILE DEFAULT LIMIT IDLE_TIME 30; -- 30分钟空闲后断开 ALTER USER EMPDB PROFILE DEFAULT;
内容的提问来源于stack exchange,提问作者Omsairam
相关产品推荐
相关产品推荐

