由于疫情,过完春节回来,远程办公,连接公司oracle数据库做开发。做了一段时间,发现后台服务无法访问数据库,用navicat连接,也是提示无法连接,所以登录服务器,查看情况;
su -oracle
sqlplus
看到提示达到了最大连接数:
ORA-00018:maximum number of sessions exceeded
索性关闭数据库重启
shutdown immediately;
startup;
问题短暂解决
过了大约一个小时以后,这个问题又出现了,应该是有oracle client一直在获取连接,致使oracle实例达到了最大连接数。
经过搜索,找到了原因,记录一下过程:
sqlplus执行如下语句:
select machine,STATUS from v$session ORDER BY STATUS;
结果:
可以看到,cluster1是我的服务器,这个连接是ACTIVE,是正常的,WorkGroup\P27JJZ这个machine是我不知道的一个机器,连接状态也基本都是INACTIVE的,查看一下它的连接数:
select count (machine) from v$session where machine='WorkGroup\P27JJZDLSK21AR0'
在我没有任何活动的情况下,一会功夫这台机器又建立了三个连接,所以终于水落石出了,就是这台不知道哪来的机器一直在连接数据库,而且连接一会状态就会INACTIVE了。
所以接下来就是两种方案:
方案一、和同事问一下,这台机器是谁的,在干嘛
在v$session中能得到这台机器的机器名称和登录的用户名,在公司群问了一下,没人知道这台机器是谁的,看来必须找到这台机器的ip地址
在 v$session 中不能直接获得客户端 IP(乱码),网上说在数据库中创建一个追踪客户端IP地址的触发器:
create or replace trigger on_logon_trigger after logon on database
begin
dbms_application_info.set_client_info(sys_context('userenv', 'ip_address'));
end;
/
这样试了也没找到ip地址,又通过v$session中的USERNAME字段,知道了oracle登录的用户,就再问了同事,找到了是哪台机器,原来是超图的IServer发布的oracle型数据库数据源,iserver会定期连接oracle数据库,但是却没有释放无用的连接,所以致使数据库连接数达到最大值,所以寻求第二方案。
方案二、实现ORACLE定时清理不活动的Session
因为很少通过IServer去查oracle数据库,所以对于IServer建立的session,可以短期就清理掉。
登录
sqlplus /nolog
conn sys as sysdba
SQL> show parameter resource;
说明资源限制已经打开;
创建一个允许3分钟IDLE时间的PROFILE:
SQL> CREATE PROFILE KILLIDLE LIMIT IDLE_TIME 3;
查看新创建PROFILE的内容:
SQL> col limit for a10
SQL> select * from dba_profiles where profile='KILLIDLE';
查看给IServer登录使用的用户的PROFILE:
SQL> select username,profile from dba_users where username='CHINA_MAP';
显示为DEFAULT
修改CHINA_MAP用户的PROFILE使用新建的PROFILE:
SQL> alter user eygle profile killidle;
至此修改完毕。