现象:数据库连接缓慢,通过disql连接大概需要10s左右,但查询数据库活动会话,SQL执行的并不慢,CPU正常,内存使用正常;总连接数4000左右,未达到最大session设置值,活动会话300-400左右;
1. 检查异常登录情况
select * from sys.sysacchistories;
--查询无结果,没有异常登录地址
2. 查询会话状态
select state,count(*) from v$sessions group by state order by 2;
可看出会话状态在STARTUP的接近3000个
select CLNT_HOST, state,count(*) from v$sessions group by CLNT_HOST,state order by 3;
连接数在应用服务器上分布的比较平均,即不是由那一台应用出问题,空白的表示还未创建成功,并且startup的状态是kill不掉的; 通过在操作系统上执行netstat anp,应用的来源ip有50多个,总连接数4000多个,分布较为平均;
怀疑应用是没有用到连接池,大量的短连接断开加重连,导致大量的链接请求;
在数据库中根据时间进行分组查询会话
select create_time,appname,count(*) from v$sessions group by create_time,appname order by create_time;
数据库中每秒创建400多个会话;
在Oracle开发规范中,每秒创建50个会话就应该引起关注了;
从应用那里了解到,开发语言为PHP,与数据库的连接是没有用到连接池的;此次事件即为大量短连接频繁连接造成的数据库连接风暴;
解决方法为:
a. 采用连接池连接数据库;
b. 将短连接改为长连接,常驻数据库;