前兩天有位朋友在QQ群問了一個問題,背景如下:
繼續問後,有如下回複:
1、對方伺服器串連無問題。
2、從client可以telnet伺服器的1521連接埠。
3、tnsping正常。
4、對方伺服器沒有設定IP信任。
5、windows 2003 server,Oracle 10.1.0.2.0
但從用戶端sqlplus就是逾時,無法串連。
首先,看下ORA-12170的定義:
oerr ora 12170
12170, 00000, "TNS:Connect timeout occurred"// *Cause: The server shut down because connection establishment or communication with a client failed to complete within the allotted time interval. This may be a result of network or system delays; or this may indicate that a malicious client is trying to cause a Denial of Service attack on the server.
// *Action: If the error occurred because of a slow network or system, reconfigure one or all of the parameters SQLNET.INBOUND_CONNECT_TIMEOUT, SQLNET.SEND_TIMEOUT, SQLNET.RECV_TIMEOUT in sqlnet.ora to larger values.
If a malicious client is suspected, use the address in sqlnet.log to identify the source and restrict access. Note that logged addresses may not be reliable as they can be forged (e.g. in TCP/IP).
大致意思就是因網路或系統問題逾時。
然後建議他能sqlnet.ora添加trace配置,看下sqlplus的跟蹤:
TRACE_LEVEL_CLIENT=16
TRACE_FILE_CLIENT=CLIENT
TRACE_TIMESTAMP_CLIENT=ON
trace_directory_client=一個路徑
但此時反饋說服務端的技術服務人員已經開啟了Oracle共用串連,現在可以sqlplus。
現在問題就出來了,什麼是Oracle共用串連?做了什麼配置就可以從用戶端訪問了?為什麼會出現這個問題?
總結來說,這個問題是和Oracle運行於Windows平台相關的。對於運行於Windows平台的,從用戶端發起一個串連請求時,服務端監聽會讓用戶端重新導向另外一個隨機連接埠。既然是一個隨機連接埠,那麼防火牆自然不會允許這個串連。因此會出現從用戶端可以telnet監聽連接埠,但sqlplus就是逾時,無法串連。究其原因就是由於用戶端真正和Oracle線程通訊時使用的隨機連接埠會被防火牆拒絕。這種情況只會發生在Windows平台,因為UNIX之類的平台是預設支援連接埠共用的,不會出現連接埠被防火牆拒絕的現象。
可行的解決方案有兩種,
1. 使用包含內建SQL*Net代理的防火牆。
流程:
1. 串連代理,將串連傳給監聽。
2. 發送用戶端重新導向地址。
3. 通過代理串連重新導向地址。
4. Oracle接受串連。
2. 升級資料庫到8.0.x以上,設定註冊表中USE_SHARED_SOCKET變數值為TRUE。
監聽器會在“listener.ora”檔案中指定的地址上綁定和建立一個socket。在這個socket中,監聽器的監聽狀態是ACTIVE。當監聽器接收串連請求時,監聽器會在監聽連接埠派生一個Oracle線程。這種情況會反覆產生,以至於最後形成了一個監聽器和一些已建立的串連都在使用1521連接埠的閉環。
從10.2以上的,USE_SHARED_SOCKET就已經是預設值為TRUE了,無需再修改。
MOS的124140.1文章詳細介紹了這部分內容,翻譯原文如下:
目的:運行於Windows NT,Windows 2000,或後續版本的作業系統,串連Oracle資料庫的Oracle Net或Net 8串連,可能會讓用戶端重新導向串連一個短連接埠範圍中的一個連接埠號碼(除非碰到下面”特殊備忘“節中的問題)。微軟WINSOCK V1.1 API不允許進程將一個TCP的socket傳給另一個進程。也就是不允許像UNIX系統中的連接埠共用。為了讓Oracle串連可以運行於防火牆環境中,客戶不得不使用包含內建SQL*Net代理的防火牆,或者使用Windows NT 4.0(可從Service Pack#3中獲得)、Windows 2000以上的版本的WINSOCK V2 API,或者Windows 2000以上的版本。這種特性也能通過在Windows註冊表中使用"USE_SHARED_SOCKET"參數在Oracle資料庫中實現。
範圍:這篇文章主要是提供給需要通過防火牆使用SQL*Net,Net8或Oracle Net串連訪問運行在Windows作業系統的Oracle資料庫的DBA和網路系統管理員。
詳細描述:正如66382.1描述的,有兩種方法可以讓Oracle資料庫運行於使用防火牆的環境中。1. 使用包含內建SQL*Net代理的防火牆。SQL*Net代理可以開啟另一個讓用戶端串連的監聽進程(通常在1610連接埠)。然後這個監聽進程會代理到資料庫的串連,並處理防火牆內部的連接埠重新導向,不會觸發禁止訪問的規則。此時防火牆就像正在運行Oracle連線管理員(Connectiong Manager或多協議交換器,Multi Protocol Interchange)。有一點不同的就是,在防火牆和資料庫之間安裝了連線管理員Connection Manager,並且安裝防火牆時允許他可以串連到連線管理員。那麼防火牆就不需要Oracle Net或SQL*Net了。2. 第二種方法是升級到8.0.x或以上版本,並在註冊表中設定參數USE_SHARED_SOCKET,目的就是為了啟用連接埠共用(在Oracle 10.2及以上中該值預設是TRUE)。這個參數在Windows NT 4.0(SP3或更高),Windows 2000,或Winsock V2支援的更高版本中可以設定。通過該參數,也能夠使用僅支援連接埠過濾以及沒有SQL*Net代理(至少是專用連線)的防火牆。多線程伺服器(MTS)仍舊需要將串連重新導向到一個動態連接埠,因此也需要SQL*Net代理。當Oracle運行於Windows作業系統時,可以通過在系統內容或Windows註冊表中設定這個參數變數來啟用連接埠共用。推薦最好在Windows註冊表中設定:USE_SHARED_SOCKET = TRUE。在Windows NT設定系統內容變數的方式:控制台-系統-環境。Windows 2000以上,也可以使用控制台的系統按鈕,但環境變數需要點擊”進階”按鈕來找到並設定。亦可以使用Windows註冊表設定:In Oracle release 8.0 \\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLEIn Oracle release 8.1 \\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME<#>
In Oracle release 9 or later \\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\Key_<Home>增加一個STRING_VALUE值(註冊表視窗右側),不是KEY值(註冊表視窗左側)。所有這些方法都需要Oracle進程的重啟,以使進程重啟時可以讀取到註冊表。
Troubleshoot備忘:可以使用‘netstat -a’命令查看配置。他應該展示所有的用戶端串連,以及監聽的連接埠。
C:\>netstat -anActive ConnectionsProto Local Address Foreign Address StateTCP 0.0.0.0:1521 0.0.0.0:0 LISTENINGTCP 198.51.100.9:1521 198.51.100.6:55769 ESTABLISHEDTCP 198.51.100.9:1521 198.51.100.91:13452 ESTABLISHEDTCP 198.51.100.9:1521 198.51.100.92:13203 ESTABLISHEDTCP 198.51.100.9:1521 198.51.100.92:13202 ESTABLISHEDTCP 198.51.100.9:1521 203.0.113.166:12331 ESTABLISHEDTCP 198.51.100.9:1521 203.0.113.10:12123 ESTABLISHEDTCP 198.51.100.9:1521 203.0.113.10:11252 ESTABLISHEDTCP 198.51.100.9:1521 192.0.2.22:14524 ESTABLISHEDTCP 198.51.100.9:1521 192.0.2.20:13524 ESTABLISHEDTCP 198.51.100.9:1521 192.0.2.102:13452 ESTABLISHEDTCP 198.51.100.9:1521 192.0.2.121:1342 ESTABLISHED
可以在用戶端SQLNET.ORA檔案中設定如下參數,來啟用Oracle Net用戶端跟蹤:TRACE_LEVEL_CLIENT= 16
TRACE_DIRECTORY_CLIENT = <directory>
TRACE_FILE_DIRECTORY= <filename>[Insert code here]通過在追蹤檔案中搜尋'port'字串,可以定位到具體的唯一連接埠。
特殊備忘:1. 如果使用TCPS協議或SSL,將會發生連接埠重新導向。解決方案是使用支援Sqlnet或Net8串連的防火牆或配置共用伺服器分發連接埠。2. 10g及以上,預設USE_SHARED_SOCKET=TRUE。