记一次Oracle session数过多引起进程数超过processes限制最终导致客户端无法连接的问题

RAC突然告警,客户端尝试连接时会报:ORA-12520: TNS:listener could not find available handler for requested type of server 错误。

现整理解决过程,以便于后续遇到此问题时快速处理。

1. 登入服务器,使用sqlplus / as sysdba 发现可以进入数据库。

2. 查看alert日志,发现日志中有个错误信息:ORA-00020: maximum number of processes (2000) exceeded,由此判断是process数超了。

alert日志的路径可以通过如下sql找到:

select * from gv$diag_info where name like ‘%Alert%‘

3. 确定出问题的Oracle用户,

select t1.inst_id,t1.username,count(*) from gv$session t1
 join gv$process t2 on t2.addr=t1.paddr and t2.inst_id=t1.inst_id
 group by t1.inst_id,t1.username order by 3 desc

可查到是xxxx用户连接数过多导致的。

4. 阻止用户再建立新的连接。

可以根据对客户端的控制程度来灵活选用处理方式。如果对客户端程序具有绝对的控制权,可将出问题的程序停掉,正常情况下问题就解决了。

我选择的方式是将用户lock,执行以下sql:

alter user xxxx account lock;

5. 此时我们查看gv$session,发现已经建立的连接还在。

select * from gv$session where username=‘XXXX‘

6. 清理这些连接。

此时不要用alter system kill session,因为经过我后续测试发现,如果出问题的客户端程序未退出,该客户端与Oracle服务端建立的网络连接是一直保持的,此时即使我们kill session,process依然不会被释放,反而会导致gv$session视图和gv$process视图失去关系,进而导致我们查不到该用户的session对应那些进程。

在操作系统层面直接kill session对应的系统进程。

使用如下sql可查到XXXX账号的session对应的系统进程号:

select t1.inst_id,t1.sid,t1.serial#,t1.username,t2.spid 系统进程id from gv$session t1
 join gv$process t2 on t2.addr=t1.paddr and t2.inst_id=t1.inst_id
 where t1.username=‘XXXX‘

7. 做完以上的操作进程的占用即可降下来。接下来就考虑与客户端沟通停掉出问题的程序然后对锁掉的账号进行恢复了。

顺便给出一个kill所有session对应的操作系统的命令,此法过于暴力,尽可能不要使用。

ps -ef | grep LOCAL=NO | grep -v grep | awk ‘{print $2}‘ |xargs kill -9

问题解决过后,我使用python在测试库中做了一下问题的复现,代码如下:

#!/bin/python
# -*- coding: utf-8 -*-
import cx_Oracle as co
conn=co.SessionPool(‘XXXX‘,‘XXXXXXXXX‘,‘x.x.x.x‘,min=1,max=5000)

a=[]
for i in range(5000):
    print(i)
    try:
        ccc=conn.acquire()
        a.append(ccc)
    except Exception as e:
        print(e)
        time.sleep(20)

以上。

原文地址:https://www.cnblogs.com/vanwoos/p/12590538.html

时间: 2024-09-29 22:17:04

记一次Oracle session数过多引起进程数超过processes限制最终导致客户端无法连接的问题的相关文章

修改操作系统句柄数和用户进程数

对于一般的应用来说(像Apache.系统进程)1024完全足够使用.但是像squid.mysql.java等单进程处理大量请求的应用来说就有点捉襟见肘了.如果单个进程打开的文件句柄数量超过了系统定义的值,就会提到"too many files open"的错误提示.怎么查看当前进程打开了多少个文件句柄呢? lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more 在系统访问高峰时间以root用户执行上面的脚本,可能出现的结果如下: #

ORACLE如何查看修改连接数,进程数及用户数,三者之间关系

SQL> select count(*) from v$session #连接数SQL> Select count(*) from v$session where status='ACTIVE' #并发连接数SQL> show parameter processes #最大连接 process:这个参数限制了能够连接到SGA的操作系统进程数(或者是Windows 系统中的线程数),这个总数必须足够大,从而能够适用于后台进程与所有的专用服务器进程,此外,共享服务器进程与调度进程的数目也被计

Oracle session连接数和inactive的问题记录

Oracle session连接数和inactive的问题记录 http://timnity.javaeye.com/blog/280383 从上周起,服务器Oracle数据库出现问题,用不到半天,就会报maxsession(150)的问题,肯定是数据库的会话超过最大数了.   由于服务器跑的是文件传输应用,占用的请求和会话肯定很大,因此用户数不大就已经让oracle的会话数达到最大值.   处理方式不外乎两种:扩大oracle最大session数以及清除inactive会话,当然还有,就是从数

记一次Oracle Clusterware成功安装后的故障处理

记一次Oracle Clusterware安装成功后的故障处理 1. 环境 [[email protected] rac1]$ cat /etc/issue Red Hat Enterprise Linux Server release 5.8 (Tikanga) Kernel \r on an \m 2. 问题描述在安装RAC的过程中, 成功安装好grid (clusterware) 后关闭了各节点. 在下次开启各节点后, 检查crs资源状态, 出现如下错误: [[email protecte

oracle session和process的关系

什么是session 通俗来讲,session 是通信双方从开始通信到通信结束期间的一个上下文(context).这个上下文是一段位于服务器端的内存:记录了本次连接的客户端机器.通过哪个应用程序.哪个用户在登录等信息[在pl/sql developer中,通过Tools-->Sessions可以查看当前数据库的session].session 是和connection同时建立的,两者是对同一件事情不同层次的描述.简单讲,connection是物理上的客户机同服务器段的通信链路,session是逻

oracle连接进程数设置

SQL> select count(*) from v$session #连接数SQL> Select count(*) from v$session where status='ACTIVE' #并发连接数SQL> show parameter processes #最大连接 process:这个参数限制了能够连接到SGA的操作系统进程数(或者是Windows 系统中的线程数),这个总数必须足够大,从而能够适用于后台进程与所有的专用服务器进程,此外,共享服务器进程与调度进程的数目也被计

Oracle在线调整redo日志组数及组成员

Oracle在线调整redo日志组数及组成员 一.调整redo日志组大小 操作原因: redo日志一般设置让日志转换时间为10-20分钟,转换太频繁会影响性能.通常情况下每小时不要超过6次!如果AWR(Automated Workload Repository 自动负载信息库) report中log file switch checkpoint incomplete) 比较大,说明redo log之间的切换过于频繁.可以通过增加redo log size来降低切换的频率.但如果redo log

《oracle每日一练Oracle DBLink连接数过多的问题(Ora-02020)》

本文转自Oracle DBLink连接数过多的问题(Ora-02020) 今天在处理资料同步问题,需要将其它几个DB Server的资料同步到一个目地资料库,采用的方式是:DBLink+Job ,然而在写过程编译时发生Ora-02020错误. 如下: 环境: 目地Server(别名:DB) 其它需要同步的Server(  DB1 , DB2,  DB3,  DB4  ,DB5) 做法: 建立各个Server的DB Link,然后在过程中同步相关的数据. 如代码: 1 create or repl

Oracle sql%rowcount 返回影响行数;sql server @@RowCount返回影响行数

sql server中,返回影响行数是:If @@RowCount<1 Oracle中,返回影响行数是:If sql%rowcount<1 例: sqlserver: create procedure Proc_test @Stat int=0, @MsgId varchar(50)='', AS BEGIN Update T_Mt Set Stat=@Stat,OStat=@Stat,RptTime=Getdate() Where MsgId=@MsgId If @@RowCount<