Sql-Server

連接超時已過期,但沒有明顯的網路問題

  • May 22, 2018

我們有一個特定的 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 地址確實會發生故障。

Wireshark 對話圖顯示伺服器超過 15 秒沒有響應

我是否正確地認為我收到對發送的登錄前請求數據包的即時 TCP ACK 會將問題本地化到作業系統或 SQL Server 的事實?

這最終被確定為 VMWare LRO 的副作用。禁用基於主機的 LRO 解決了該問題。看

引用自:https://dba.stackexchange.com/questions/188255