From:威哥
之前项目在进行压测的过程中,客户的数据库发生宕机,但是当客户数据库恢复后,数据库(Oracle)出现了大量连接数,直接锁住数据库。将之前的总结文档记录到博客:
历史疑点
1.情景无法重现
现只能重现过以下情景,且只存在当连接池中连接数逼近数据库设置的并发数时才会出现数据库无法通过客户端或者sqlplus等登录失败的情况;
- 数据库服务正常运行场景下的1521端口连接统计,数据库连接池中连接统计;
- 数据库服务正常运行场景下的压力测试运行中的1521端口连接统计,数据库连接池中连接统计;
- 数据库服务正常运行场景下的压力测试执行完毕5分钟后的1521端口连接统计,数据库连接池中连接统计;
- 数据库服务在程序运行过程中修改用户密码场景下执行压力测试运行中1521端口连接统计,数据库连接池中连接统计;
- 数据库服务在程序运行过程中停止数据库服务场景下执行压力测试运行中1521端口连接统计,数据库连接池中连接统计;
- 在压力测试条件下用错误数据库密码启动程序场景下1521端口连接统计,数据库连接池中连接统计。
2.数据库连接过多具体有多少?
能否确定有效连接是否超过连接池上线300,数据库中的并发连接数设置的是多少?
3.连接使用结束后未能及时关闭是指多久未关闭?
配置为5分钟内未使用,则回收。
连接配置变更
2017年9月19日前的配置
参数名 | 参数值 | 解释 |
initialSize | 10 | 初始连接数 |
minIdle | 10 | 最小连接数 |
maxActive | 200 | 最大连接数 |
maxWait | 60000 | 超时等待时间 |
timeBetweenEvictionRunsMillis | 60000 | 关闭空闲连接的检测时间间隔 |
minEvictableIdleTimeMillis | 300000 | 连接的最小生存时间 |
validationQuery | SELECT 1 from dual | 验证数据库服务可用性的sql |
testWhileIdle | true | 申请连接时检测空闲时间,根据空闲时间再检测连接是否有效 |
testOnBorrow | false | 申请连接时直接检测连接是否有效 |
testOnReturn | false | 归还连接时检测连接是否有效 |
poolPreparedStatements | true | 开启PSCache |
maxPoolPreparedStatementPerConnectionSize | 20 | 设置PSCache值 |
2017年9月19日后追加的配置
参数名 | 参数值 | 解释 |
connectionErrorRetryAttempts | 3 | 连接出错后再尝试连接三次 |
breakAfterAcquireFailure | false | 数据库服务宕机自动重连机制 |
asyncInit | true | 异步初始化策略 |
2018年7月27日后更改的配置
参数名 | 参数值 | 解释 |
breakAfterAcquireFailure | true | 数据库服务宕机自动重连机制 |
当前问题分析
如关闭数据库服务器宕机自动重连机制后,如果出现数据库服务无法正常访问(后又能正常访问),则必须重启应用服务器。
拟解决方案
修改连接配置
参数名 | 参数值 | 解释 |
breakAfterAcquireFailure | true | 数据库服务宕机自动重连机制 |
timeBetweenConnectErrorMillis | 300000 | 连接出错后重试时间间隔 |
- 启用数据库服务断线自动重连机制:保障数据库服务修复后系统自动重连,无需重新启动应用服务;
- 修改连接出错后重试的时间间隔:由30秒改为5分钟,降低数据库服务故障期间的申请链接的请求;
- 建议修改oracle数据库最大并发数:从数据库服务端提升并发能力。
- 建议启用oracle数据库连续登陆失败锁定用户机制:避免由于修改用户密码引起的其他问题。
- 建议提高数据库高可用性。
附数据库连接参数: