ORACLE ORA-12519, TNS:no appropriate service handler found

背景:在日常运维工作中,各种各样的问题,真是千奇百怪。今天遇到这个问题了,查了一些解决办法,做了一个汇总,今天就分享一下。

错误:ORA-12519, TNS:no appropriate service handler found

[ ~]$ oerr ora 12519
12519, 00000, "TNS:no appropriate service handler found"
// *Cause: The listener could not find any available service handlers that
// are appropriate for the client connection.
// *Action: Run "lsnrctl services" to ensure that the instance(s) have
// registered with the listener, and are accepting connections.

主要从两个方面来考虑这件事,从程序方面来看:

    1.进行数据库连接操作后未释放连接;

    2.若使用了数据库连接池,则考虑连接池的超时设置。

从数据库本身来看:

    1.可以增加数据库的最大连接数;

    2.可以定时清理数据库中INACTIVE的会话。

对运维人员来说,只能从数据库本身入手:
 

select count(*) from v$process;   --目前的会话
select value from v$parameter where name = ‘processes‘ ;  --最大会话   一般生产环境processes参数设置为2000,如果应用特别多的,可以设置为3000.

查看从哪里连接的Oracle链接数:
select  b.MACHINE, b.PROGRAM , count(*) from v$process a, v$session b where a.ADDR = b.PADDR and  b.USERNAME is not null   group by  b.MACHINE  , b.PROGRAM order by count(*) desc;
 
定时清理INACTIVE会话需要创建一个存储过程找出超过2小时(根据需求设定)的会话,然后断开会话,具体如下:
CREATE OR REPLACE PROCEDURE DB_KILL_IDLE_CLIENTS AUTHID DEFINER AS--AUTHID DEFINER可省略。
  job_no       number := 0;
  num_of_kills number := 0;
BEGIN

  FOR REC IN (SELECT SID, SERIAL#, INST_ID, MODULE, STATUS
                FROM gv$session S
               WHERE S.USERNAME IS NOT NULL
                 AND S.LAST_CALL_ET >= 2 * 60 * 60
                 AND S.STATUS = ‘INACTIVE‘
               ORDER BY INST_ID ASC) LOOP
    DBMS_OUTPUT.PUT(‘LOCAL SID ‘ || rec.sid || ‘(‘ || rec.module || ‘)‘);
    execute immediate ‘alter system disconnect session ‘‘‘ || rec.sid || ‘, ‘ ||
                      rec.serial# || ‘‘‘immediate‘;
   
    DBMS_OUTPUT.PUT_LINE(‘. killed locally ‘ || job_no);
    num_of_kills := num_of_kills + 1;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE(‘Number of killed system sessions: ‘ || num_of_kills);
END DB_KILL_IDLE_CLIENTS;
创建定时任务执行这个存储过程:

begin
  sys.dbms_job.submit(job       => :job,
                      what      => ‘SYS.DB_KILL_IDLE_CLIENTS;‘,
                      next_date => to_date(‘25-05-2018 17:00:00‘,
                                           ‘dd-mm-yyyy hh24:mi:ss‘),
                      interval  => ‘TRUNC(sysdate,‘‘hh‘‘) + 1/(24)‘);
  commit;
end;
注意以sys角色登录操作
————————————————
 --单次使用:SELECT ‘alter system disconnect session ‘‘‘ || sid || ‘,‘ || serial# ||       ‘‘‘ immediate;‘  FROM (SELECT SID, SERIAL#, INST_ID, MODULE, STATUS          FROM gv$session S         WHERE S.USERNAME IS NOT NULL           AND S.LAST_CALL_ET >= 2 * 60 * 60           AND S.STATUS = ‘INACTIVE‘         ORDER BY INST_ID ASC)                  查出来的语句执行即可。————————————————版权声明:本文为CSDN博主「京斗码农」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_42163563/java/article/details/90294916