記錄一次ORA-12516 process爆滿的特殊故障

ORA-12516: TNS: 監聽程序找不到符合協議堆棧要求的可用處理程序

ORA-12520: TNS: 監聽程序無法爲請求的服務器類型找到可用的處理程序

這兩個錯誤很常見了,意思是oracle進程數已滿了.導致oracle無法分配出process處理客戶的連接.一般的解決辦法就是加大process,但是我們這裏卻不是這種情況.

客戶的環境是AIX-10.2.0.4  首先在process爆滿的時候,我們查詢了v$process和v$session,發現process數有3000,而v$session只有300,這是很不正常的,正常情況下應該是差不太多.

以前遇到過由於密碼錯誤導致的process爆滿的情況,所以懷疑是有帳號密碼錯誤登錄導致,所以使用下面的觸發器檢查是否有錯誤密碼登錄:

CREATE OR REPLACE TRIGGER logon_denied_to_alert
  AFTER servererror ON DATABASE
DECLARE
  message   VARCHAR2(168);
  ip        VARCHAR2(15);
  v_os_user VARCHAR2(80);
  v_module  VARCHAR2(50);
  v_action  VARCHAR2(50);
  v_pid     VARCHAR2(10);
  v_sid     NUMBER;
  v_program VARCHAR2(48);
BEGIN
  IF (ora_is_servererror(1017)) THEN

    -- get ip FOR remote connections :
    IF upper(sys_context('userenv', 'network_protocol')) = 'TCP' THEN
      ip := sys_context('userenv', 'ip_address');
    END IF;

    SELECT sid INTO v_sid FROM sys.v_$mystat WHERE rownum < 2;
    SELECT p.spid, v.program
      INTO v_pid, v_program
      FROM v$process p, v$session v
     WHERE p.addr = v.paddr
       AND v.sid = v_sid;

    v_os_user := sys_context('userenv', 'os_user');
    dbms_application_info.read_module(v_module, v_action);

    message := to_char(SYSDATE, 'YYYYMMDD HH24MISS') ||
               ' Password Error ,logon denied from ' || nvl(ip, 'localhost') || ' ' ||
               v_pid || ' ' || v_os_user || ' with ' || v_program || ' – ' ||
               v_module || ' ' || v_action;

    sys.dbms_system.ksdwrt(2, message);

  END IF;
END;
/

上面的觸發器會將密碼錯誤的登錄寫到alert日誌中.

我們這裏也沒有發現有錯誤密碼登錄.所以我查閱了一下MOS,搜索到一篇文檔:

這裏文檔中也說明了,process很高,session很低說明有很多進程連接到數據庫,但是連接失敗了,所以導致process比session高很多

文檔裏面也說了一種情況就是密碼錯誤.

因此我們可以定位到問題的原因是:

有大量的客戶端連接到了數據庫,數據庫在分配了進程處理連接之後,連接失敗了,但是oracle分配了進程處理就會佔用一個process,不管他是否成功還是失敗,由於大量的失敗進程導致進程數爆滿.

那麼具體是什麼IP什麼程序,連接到數據庫呢?

這裏我們可以想到可以通過監控tns日誌的方式獲取連接IP和程序的信息.查出異常的IP地址,再通過使用tns黑名單的方式將此IP封掉.

我們這裏最後定位發現的是一個應用程序連接數據庫,每次連接之後停留在輸入用戶名和密碼階段,而且每次都是批量產生大量的連接,導致客戶進程爆滿.

由於此進程還沒有連接到數據庫,所以在數據庫級別是查不到任何信息的,只能從監聽層面分析.

總結一下,遇到此問題的處理:

1.創建密碼錯誤觸發器,檢查是否有錯誤密碼登錄(一般都是此問題,像我這次遇到的及其難得)

2.查看監聽日誌,最好寫一個腳本能夠統計出最近的連接的IP訪問次數,使用awk來處理還是不難的

3.查出了是哪個ip,再配置sqlnet,將IP添加到黑名單中,這樣直接在TNS層就將此連接拒絕,

4.最後再到此IP的機器上檢查應用是否有問題.

 

發佈了162 篇原創文章 · 獲贊 31 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章