1. 程式人生 > >連線池 執行SQL超時15分鐘

連線池 執行SQL超時15分鐘

1、排查問題

這次上線遇到客戶端假死15分鐘左右才能繼續處理業務的問題。發現是在執行SQL時一直在等待15分鐘後才能返回sql執行失敗。檢視日誌錯誤是 ORA-03113: end-of-file on communication channel從這個錯誤看,應該是Oracle客戶端返回了連線斷開的錯誤,但是為什麼要15分鐘後才返回這個錯誤呢? 在網上找了很久,終於在防火牆斷開資料庫或者mq的連線造成的長時間重連等待找到了我想要的東西,猜測是由於防火牆刪除了會話,但主機並不知道,有資料庫操作的時候,由Oracle客戶端發起TCP請求,但由於防火牆找不到會話,丟棄了這些包(目前是不是丟還不清楚),導致了TCP不停地超時重發。

2、為什麼防火牆刪除會話後,主機要等15分鐘?

檢視TCP/IP詳解第一卷的21章節21.2節,都超時重發有這樣的描述:參考資料1

TCP超時重發

這裡提到9分鐘,不過這本書寫得比較早,猜測linux有所不一樣,不過原理差不了太多,google了一下,

好像找到了15分鐘的說法, 參考資料2中提到:

TCP_RTO_MIN=(HZ/5)=0.2s TCP_RTO_MAX=(120HZ)=120s linear_backoff_thresh = ilog2(1205)=ilog2(0x258)=9 timeout:未超過linear_backoff_thresh=9的部分按TCP_RTO_MIN 2的指數倍增長,超過的部分按TCP_RTO_MAX線性增長 tcp_time_stamp:當前時鐘時間 例如資料傳送階段,sysctl_tcp_retries2=9,則timeout=1023TCP_RTO_MIN=204.6s;sysctl_tcp_retries2=11時,timeout=1023

TCP_RTO_MIN+2TCP_RTO_MAX=448.6s 預設sysctl_tcp_retries2=15,timeout=1023TCP_RTO_MIN+6*TCP_RTO_MAX=920.6s,約15分鐘

是根據RTO及一定的演算法算出來的(具體的演算法,可以看參考資料3)

簡單說,就是如果系統配置重傳次數小於9的話,就是指數增長時間,如果大於9的話,就是最大超時時間。

而linux預設是15,所以剛好是15分鐘,檢視我們主機的配置,確認是15:

[[email protected] ~]$ cat /proc/sys/net/ipv4/tcp_retries2
15

現在還有一個問題沒弄清楚,就是防火牆刪除會話後,是否會通知主機?現在看起來應該是不會的,至少在主機上是沒收到防火牆的RST,由於兩個防火牆的兩個廠商不一樣,也有可能是一個吃掉另外一個的包也說不定。假如刪除會話後,在原來的會話上來有包上來,是重建會話呢?還是直接把包丟棄?還是發RST呢?從目前主機的現象來看,猜測是:

防火牆刪除會話後,不會通知主機也就是不會給主機發RST,當有新包上來,找不到連線,但不是S包的時候,直接丟棄,

導致主機用完了重發次數後,自己發RST後給應用報斷開連線。

3、解決方案

1、修改net.ipv4.tcp_retries2=5參考資料4 2、修改防火牆策略

【參考資料】