java.sql.SQLRecoverableException: IO Error: Socket read timed out 排查歷程

darren__chan發表於2020-06-28

一:

12c遷移19c工程,針對大資料相關定時作業進行效能對比,發現部分作業連線19c 出現 Socket read timed out 問題,並且可以復現,該部分作業連線12c並無異常

初步排查情況如下:

1)在執行到某部分sql時jdbc丟擲Error: java.io.IOException: SQLException in nextKeyValue 錯誤,導致的原因是Caused by: java.sql.SQLRecoverableException: IO Error: Socket read timed out 

2)jdbc堆疊資訊無ora錯誤,看起來是一個客戶端單方面錯誤

3)連續檢視幾次報錯日誌,發現每次報錯都是在發起sql後的第11分鐘才丟擲異常,詢問客戶是否有進行timeout相關測試,客戶反饋連線串中未設定任何引數

4)對該場景進行重現測試,發現客戶端報出Socket read timed out,資料庫會話依然在執行直到sql執行結束

5)關於socket read timed out初步瞭解到是客戶端在向資料庫發起查詢時等待資料返回時超過了某個時間限制導致超時

6)瞭解到jdbc driver版本是11.2.0.1.0


二:

1)jdbc driver 版本11.2.0.1是不相容19c,建議客戶先進行升級測試

2)需要進一步排查網路是否有超時設定

3)透過以上步驟來縮小排查範圍

2.討論進展如下:

1)客戶否認網路存在問題,但我認為是否可以繼續進行抓包排查

2)客戶表示驅動包問題可以進行升級驅動測試,確認是否驅動包問題

3)提出每次報錯都是在第11分鐘開始報錯,客戶提出可能應用平臺有配置過10分鐘的超時設定,開發排查程式碼發現有10分鐘超時設定,後面增加超時時間再進行測試,發現不再報錯

4)客戶存在疑問,為何同樣的配置在12c不生效,而在19c能夠生效

5)現場同時排查了資料庫端sqlnet引數,12c和19c並無差別


三:

1)詢問中介軟體同事,表示針對不同資料庫版本可能會有不同的超時時間設定,這一點找不到相關資料,詢問sr,gcs表示沒有不同的設定說法

2)中介軟體同事和sr同時也建議排查作業系統層,目前只能看到資料庫端os,目前看到的網路相關引數不確認。

3)客戶在測試環境使用11.2.0.4版本jdbc 進行測試,發現同樣在12c不會超時,而在19c會出現超時

4)為了排除資料版本不同造成socket超時不生效原因,我使用一段java程式碼指定不同版本的jdbc driver 分別連線12c和19c 進行查詢操作一段,設定socket timeout 時間為10s,發現11.2.0.1和11.2.0.4 的jdbc driver 連線12c和19c 查詢超過10s後 都能出現超時情況,進一步可以說明超時是否生效與資料庫版本無關,同時也和jdbc版本無關,所以問題還是出現在應用端配置上,將此情況向客戶反饋。


四:

1)將java測試程式碼 readtimeout 從10秒鐘調整為10分鐘,看是否能復現客戶的問題。

2)調整為10分鐘進行測試,結果是19c 正常10分鐘超時,12c 10分鐘超時。

3)與gcs jdbc 工程師討論,懷疑12c超時不生效是因為客戶端socket api在監測時不斷接收到資料包,導致超時時間被不斷延長。

4)協調系統工程師進行連線12c和19c的網路抓包測試,發現連線12c時,db端每2分鐘會傳送一個10 bytes的tns包到client端,隨後client端會返回ack包。而連線19c時,db端每2分鐘傳送一個keep-alive包到client端。從db端來看,目前配置了sqlnet.expire_time=2,可能與此有關。

5)與gcs工程師討論,12c為何timeout不生效就應該是定時tns包影響,而19c timeout生效是因為keep-alive 包是相對比較底層的資料包,client端作業系統直接過濾掉。


五:

1)查詢文件 Oracle Net 12c: Changes to the Functionality of Dead Connection Detection (DCD) (Doc ID 1591874.1) 發現 在12c後 ,開啟dcd後db端檢測死連線的方式是從每n分鐘傳送10 bytes tns包改成了 tcp keep-alive包,這裡可以解釋19c網路抓包中看到的每2分鐘一個的keep-alive包。

2)但目前來看,連線12c是使用了傳統的tns包,而19c是使用了新的keep-alive包, 從文件1591874.1中看是12.1之後就預設使用了新的模式,但如果作業系統不支援或者認為設定,可以改為傳統傳送tns包的模式,目前12c是solaris 11.3作業系統,是支援keep -alive的,理論是應該支援新模式的,目前找不到更多資料說明,這仍是是個謎團。



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

相關文章