Alert Log中“Fatal NI connect error 12170”錯誤問題
定期檢查資料庫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”問題,從本質上是由於長串連資料庫互動方式造成的,嚴格意義上不應算什麼錯誤問題。如果是一些三層架構體系應用,可以考慮使用串連池進行動態資源撫平的方式,對問題進行緩解。