Sql-Server
連接超時已過期,但沒有明顯的網路問題
我們有一個特定的 SQL Server,它在接受連接時會間歇性地超時。這個問題在一天中是一致的,但發生率非常低。如何繼續排除故障?
連接超時已過期。嘗試使用登錄前握手確認時超時時間已過。這可能是因為登錄前握手失敗或伺服器無法及時響應。嘗試連接到此伺服器所花費的持續時間是 -
$$ Pre-Login $$初始化=0;握手=15002;(Microsoft SQL Server,錯誤:-2)
伺服器配置:
- SQL Server 2016 SP1 CU5 Enterprise(在 SP1 之前也出現過問題)
- 伺服器和客戶端上的 Windows Server 2012 R2
- HP ProLiant DL360 Gen9 上的 VMware ESXi,6.5.0
- VM 有 8 個 vCPU,64 GiB 記憶體(完全保留)
測試腳本(每秒執行一次):
$failed = $false; $loginDuration = (Measure-Command { $ncon = New-Object System.Data.SqlClient.SqlConnection ` @( 'Data Source=1.2.3.4,16143;Database=Test;User=Test;Password=****;Pooling=false;' ); try { $ncon.Open(); $cmd = New-Object System.Data.SqlClient.SqlCommand ` @( 'SELECT @@VERSION', $ncon ); $cmd.ExecuteNonQuery(); $ncon.Dispose(); } catch { $failed = $true; } }).TotalMilliseconds; Write-Metric -metric 'itp.dbserver.logintime' -unit 'milliseconds' ` -value (&{if ($failed) { 120000 } else { $loginDuration }});
觀察:
- 在作業系統更新、SQL Server 更新、San 移動以及從 Hyper-V 移動到 VMWare 之後開始出現問題
- 大多數連接成功(1,440 次嘗試中有 4 次失敗)
- 失敗總是在“$$ Pre-Login $$初始化 = 0;”和“握手 = 15002”中的一個高數字。我們沒有收到像“未找到”或“不知道這樣的主機”這樣的錯誤,只有“連接超時”
- 沒有為監聽器啟用加密
- Ping 顯示在較長時間內沒有失去(發送的 96,045 次中有 0 次失去)
- 所有防火牆都被禁用
- 嘗試使用 IPv6 和 IPv4 地址的連接失敗率相同
- CPU 偏低 (<40%)
- 活躍會話持續在 400 左右
- 氣球驅動程序已禁用
- 一旦建立的連接是穩定的,執行查詢時沒有意外錯誤,沒有奇怪的斷開連接。
- 多個客戶端在連接時遇到問題 - 來自多台電腦的 ODBC 和 ADO
*更新:*我終於得到了一個失敗連接的客戶端 Wireshark 跟踪。沒有明顯的封包遺失,客戶端實時接收 TCP ACK(<10ms)。發生故障時客戶端使用 DNS 名稱,但使用連接字元串中的 IPv4 地址確實會發生故障。
我是否正確地認為我收到對發送的登錄前請求數據包的即時 TCP ACK 會將問題本地化到作業系統或 SQL Server 的事實?
這最終被確定為 VMWare LRO 的副作用。禁用基於主機的 LRO 解決了該問題。看