dcd 起初是專為 客戶機沒有從會話中斷開聯接的情況下斷電的環境設計的.
dcd由服務端開始建立聯接. 這時候sql*net 從參數文件中讀取變量, 設置一個定時器定時產生信號. 這個時間間隔是sqlnet.ora文件中的sqlnet.expire_time提供的.
當定時器設定的時間到了之后, 服務器上的sql*net 發送一個探測包到客戶端.(如果是數據庫聯接, 目的端的服務器發送探測包到另一端). 探測包是由空的sql*net包組成, 不體現sql*net層任何數據, 但會在下一層的網絡協議中產生數據流量.
如果客戶端的聯接仍然是活動的, 探測包被丟棄. 計時裝置復位. 如果客戶端異常斷掉. 服務器將收到由發送探測包的調用發出的錯誤. sql*net 將會通知操作系統釋放聯接占用的資源.
在unix服務器上 sqlnet.ora 文件必須存在$tns_admin 或者 $oracle_home/network/admin目錄下. 而不是/etc 或者 /var/opt/oracle
同時也應該注意, sql*net 2.1.x中 一個活動的孤兒進程(例如, 單獨的查詢進程) 在查詢完成之前不會被殺掉. sql*net 2.2中孤兒進程占用的資源將會被無條件釋放.
這只是服務器的特性, 客戶端將會支持任何sql*net v2 的發行版
協議棧的功能
雖然 死聯接檢測是在sql*net層的, 但要成功執行在很大程度上要依靠下層協議棧. 例如, 如果在sqlnet.ora文件中 設置sqlnet.expire_time=1, 但是一個孤兒進程很有可能在間隔到了之后被清除掉.
tcp/ip協議是一個面向聯接的協議, 同樣的, 這個協議在超時時執行重傳數據包的操作, 確保數據的安全和數據包的順序. 如果對探測包沒有及時回應, tcp/ip棧將在一段時間內重傳這個包. 當tcp/ip放棄重傳之后, sql*net 將會收到 探測失敗的通知.
tcp/ip超時的時間取決于 tcp/ip棧, 超時很多分鐘是很常見的, 這個涉及到很多客戶, 許多協議層的重傳會造成孤兒進程被殺掉之前要等很長時間.
最簡單的辦法檢測協議棧有這個延遲需要測試不同的dcd間隔.
測試協議棧
設置參數sqlnet.expire_time = 1 min, 注意清除孤兒進程需要的時間. 然后設置為 5min,
再次觀察這個時間. 如果服務器沒有釋放資源是由于tcp/ip超時造成的, 清除影子的時間需要增加到4min.
如果tcp/ip超時重傳是造成問題的所在, 操作系統的內核參數應該調整一下, 在unix平臺下, /usr/include/netinet/tcp_timer.h 中包含著配置參數.
減小重傳間隔可能會影響系統的其它部分, 因為實際上減小了聯接處理數據的窗口, 可能會在系統重負荷的情況下丟失聯接, 遠程慢的聯接會受到這個更改的影響。
系統參數會影響超時重傳的有 tcp_ttl, tcptv_persmin, tcptv_max, 和 tcp_lingertime等。
********************
為了防止對系統其他進程產生影響, 在調整系統參數時最好向相關的廠家咨詢
*******************
監控 死聯接檢測
檢測dcd是否打開和運行正常最好的方法就是 產生一個服務跟蹤文件, 查找 dcd探測包.
要產生一個服務跟蹤文件, 在sqlnet.ora文件中設置trace_level_server=16, tace_directory_server=<路徑>;, 跟蹤文件svr_
dcd 是否打開?
在跟蹤文件中查找:
osntns: enabling dead connection detection (1 min)
時間間隔應該和sqlnet.expire_time的一樣.
dcd是否正常工作?
在跟蹤文件中應該有類似:
|
代表探測包, 是由10個字節組成, 當協議頭和尾被加上后, 這個包大概有70個字節長,
如果dcd是打開的, 當定時器的時間到了之后, 在跟蹤文件里會看到探測包. 在unix系統下, 可以用:
tail -f svr_
了解dcd的問題和局限
在很少的問題報告中, 最值得注意的是dcd在windosnt下很差的性能, 死聯接只有在服務起重啟或者數據庫重啟的情況下被清除. dcd在nt下怎樣正確的工作依靠客戶端的協議. sql*net v2.3 比其他發行版改進了一些性能。
見bug#303578
在sco unix下, 有個問題是 當dcd定時器到時后, 服務進程死循環, 消耗了大量的cpu資源, 這個問題是由于不正確的信號處理造成的, 可以禁止dcd來解決
見bug#293264
如果只是客戶應用結束, 孤兒進程的資源不會被釋放, 只有當客戶端重啟之后, dcd才是放這些資源, 例如, windows應用被殺掉, 客戶端仍在運行, 探測包可以被收到, 像進程仍然活動著一樣被丟掉. 看起來好像dcd檢測客戶端機器, 而不是客戶端進程.
見bug#280848
dcd依靠探測包來檢測聯接, 所以在半雙工的網絡協議中, 這是不可能的, 所以dcd在appc/lu6.2 等半雙工協議下不能用.
內網聯接是用beq協議不能支持dcd, ipc協議可以使用
dcd 在協議層是很消耗資源的, 所以如果要用dcd來清除死進程, 會加重系統的負擔, 任何時候, 干凈的退出系統, 這是首要的。
新聞熱點
疑難解答