Fatal NI connect error 12170 錯誤

白石溪頭發表於2018-08-08

定期檢查資料庫alert log資訊,是我們進行資料庫日常維護、巡檢和故障排除的重要工作手段。資料庫系統“帶病執行”、“負傷執行”往往是“小病致死”的主要殺手。所謂“防患於未然”就需要資料庫管理員從日常的小事微情入手,時刻了解系統執行情況,並儘早進行處理。

本文主要介紹筆者使用 Oracle  11gR2過程中日誌巡檢中出現的問題,雖然最後沒有得到圓滿解決。記錄下來,留待需要朋友待查。

1、問題說明

筆者使用的一套開發環境,資料庫版本是11gR2,小版本號為11.2.0.4。

SQL> select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

PL/SQL Release 11.2.0.4.0 - Production

CORE    11.2.0.4.0 Production

TNS for Linux: Version 11.2.0.4.0 - Production

NLSRTL Version 11.2.0.4.0 – Production

在巡檢資料庫alert log過程中,發現一些錯誤提示。

Tue May 19 23:04:55 2015

*************************************

Fatal NI connect error 12170.

  VERSION INFORMATION:

        TNS for Linux: Version 11.2.0.4.0 - Production

        Oracle Bequeath NT Protocol Adapter for Linux: Version 11.2.0.4.0 - Production

        TCP/IP NT Protocol Adapter for Linux: Version 11.2.0.4.0 - Production

  Time: 19-MAY-2015 23:04:55

  Tracing not turned on.

  Tns error struct:

    ns main err code: 12535

   

TNS-12535: TNS:operation timed out

    ns secondary err code: 12560

    nt main err code: 505

   

TNS-00505: Operation timed out

    nt secondary err code: 110

    nt OS err code: 0

  Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=172.xx.xx.xx)(PORT=50741))

相同型別錯誤在日誌中反覆出現,每天出現頻率在10條左右,區別在於每次的Host對應IP地址不同。

2、問題分析

這型別錯誤在11gR2版本中經常出現。筆者之前的一些投產系統中,也常常出現這樣的問題。當前進行開發的系統架構比較傳統,是一個典型CS架構方式。客戶端桌面應用是一個富客戶端軟體,所有業務邏輯都在客戶端。客戶端直接連線資料庫。

這種架構方式是比較傳統的方式,行業內對於這種方式的缺陷已經討論很多年了。單從資料庫角度看,這樣的架構方式意味著更加多的資料庫連線數量和更加頻繁的訪問結構。

利用IP地址,我們可以從監聽器日誌listener.log中,可以定位到這個IP地址連線是什麼時候連線過來的。

[oracle@localhost trace]$ pwd

/u01/app/diag/tnslsnr/localhost/listener/trace

[oracle@localhost trace]$ cat listener.log | grep 172. xx.xx.xx

19-MAY-2015 13:51:10 * (CONNECT_DATA=(CID=(PROGRAM=JDBC Thin Client)(HOST=__jdbc__)(USER=visvim))(SERVICE_NAME=sicsdb)) * (ADDRESS=(PROTOCOL=tcp)(HOST=172.xx.xx.xx)(PORT=50741)) * establish * sicsdb * 0

從MOS上的資訊反饋看,這個型別錯誤提示是一種正常的Oracle工作機制。當客戶端程式Client Process與伺服器程式Server Process建立聯絡之後,兩者就形成了“同生共死”的關係(專有連線模式)。除非客戶端主動發起中斷或者Server Process被異常kill。

在實際執行環境中,這種理想狀態常常被打破。如果Client Process只是保持連線,不執行語句,會話就處於idle狀態。這種連線很容易被諸如防火牆等網路層面裝置切斷。

在Oracle11gR2中,如果長期沒有連線動作的Server Process被外力切斷,Oracle就會自動將資訊作為提示錯誤寫入到alert log中,作為一種提示。在11R1版本中,這種資訊是會寫入到sqlnet.log中。

3、問題解決措施

歸納MOS和網路中的各種方法,大體有兩重策略,分別為使用DCD和禁用ADR。

DCD全稱Dead Connection Detection,是一種基於主動測探方式檢查Oracle殭屍客戶端程式Client Process的策略。配置DCD的關鍵是設定sqlnet.expire_time引數在SQL Net體系下,Oracle會依據這個時間間隔給所有的Client Process傳送網路通訊包,用來確定Client是否存活。

正是藉助這個包通訊,可以讓防火牆認為這個網路連線還是處在active狀態,不會進行強制斷開動作。類似的機制還有Linux上的tcp keep live機制,也是使用類似的策略進行檢查。

[oracle@localhost trace]$ cd /u01/app/oracle/network/admin/

[oracle@localhost admin]$ ls -l

total 16

-rw-r--r--. 1 oracle oinstall  343 Sep  2  2014 listener.ora

drwxr-xr-x. 2 oracle oinstall 4096 Jun 16  2014 samples

-rw-r--r--. 1 oracle oinstall  381 Dec 17  2012 shrept.lst

-rw-r--r--. 1 oracle oinstall    0 Sep  2  2014 sqlnet.ora

-rw-r-----. 1 oracle oinstall  308 Sep  5  2014 tnsnames.ora

[oracle@localhost admin]$ cat sqlnet.ora 

[oracle@localhost admin]$ cat sqlnet.ora 

sqlnet.expire_time=10

另一種方式也是Oracle推薦的,就是關閉11g的ADR機制。ADR(Automatic Diagnostic Repository)是Oracle進行自動診斷、自動提醒的工具元件。Oracle認為如果使用者不需要在SQL Net元件中應用ADR,可以再sqlnet.ora中進行配置關閉。

[oracle@localhost admin]$ cat sqlnet.ora 

sqlnet.expire_time=10

DIAG_ADR_ENABLED = OFF

DIAG_ADR_ENABLED_LISTENER=OFF

之後,重新reload監聽器配置,或者重啟監聽器。

[oracle@localhost admin]$ lsnrctl reload

LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 21-MAY-2015 10:13:34

Copyright (c) 1991, 2013, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))

4、結論

資料庫“Fatal NI connect error 12170”問題,從本質上是由於長連線資料庫互動方式造成的,嚴格意義上不應算什麼錯誤問題。如果是一些三層架構體系應用,可以考慮使用連線池進行動態資源調配的方式,對問題進行緩解。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31440090/viewspace-2199373/,如需轉載,請註明出處,否則將追究法律責任。

相關文章