Sql-Server

遠端電腦無法使用反斜杠連接到實例

  • August 4, 2021

我們正在將 Win7 電腦上的兩個 SQL Server 2008 實例遷移到 Win10 伺服器上的 SQL Server 2019。舊伺服器有兩個實例:123.123.123.123 和 123.123.123.123\ABC。我們從所有聯網電腦連接到這兩個實例都沒有問題。

在新伺服器上,實例為:CMP0123456 和 CMP0123456\ABC。我們可以連接到沒有斜線的實例,但我們不能連接到有斜線的實例。錯誤是 SQL 錯誤 17:伺服器不存在或訪問被拒絕。

ping CMP0123456 適用於遠端電腦。

我檢查了配置管理器,並且 SQL Server 和 SQL Server 代理服務正在為這兩個實例執行。瀏覽器也在執行。兩個實例都使用 TCP/IP 和共享記憶體協議。命名管道被禁用。

我可以通過本地 SSMS 訪問這兩個實例。

我不是 DBA。我沒有設置舊伺服器或 SQL Server 2008。我對網路問題只是隱約熟悉。我檢查了新伺服器上的防火牆,並且埠 1433 和 1434 都已啟用/打開。1433 使用 TCP,1434 使用 UDP。

出於某種原因,PolyBase 有埠 1433 和 1434。我安裝了 PolyBase,但我認為我真的不需要它。如果這是問題所在,有沒有辦法將埠 1433 和 1434 直接關聯到 SQL Server 2019?

或者我需要更改 SQL Server 和/或防火牆/網路/DNS 中的其他設置,以便遠端電腦看到 \ABC 實例?

每個 SQL Server 實例偵聽不同的埠。您的預設實例正在偵聽埠 1433,但命名實例必須在不同的埠上偵聽以避免衝突,預設情況下是動態分配的。

確保防火牆也允許命名實例埠的 TCP 連接。動態埠號可以使用 SQL Server 配置管理器 (C:\Windows\System32\SQLServerManager15.msc) 辨識,並且還會在啟動時記錄到 SQL Server 錯誤日誌中(例如“伺服器正在偵聽

$$ ‘any’ 12345 $$”)。 為避免命名實例動態埠號更改時出現連接問題,請為命名實例分配靜態埠號(連同 TCP 防火牆規則)或為命名實例 SQL Server 應用程序執行檔(例如 C:\Program Files \Microsoft SQL Server\MSSQL15.ABC\MSSQL\Binn\sqlservr.exe")。

在遠端電腦上執行以下 PowerShell 命令以驗證每個實例的 TCP 埠連接。

Test-NetConnection 123.123.123.123 -Port 1433 # default instance
Test-NetConnection 123.123.123.123 -Port 12345 # specify named instance port number

在客戶端連接字元串中指定實例名稱(而不是埠號)時使用SQL Server Browser 。客戶端 API 向瀏覽器服務發送一個 UDP 1434 請求,瀏覽器服務返回一個包含目前命名實例埠號的數據報,以供後續使用。這意味著 SQL Server Browser 服務正在執行,並且允許 UDP 1434 通過防火牆,以便按名稱連接到命名實例。

不幸的是,沒有內置的 PowerShell 命令來測試遠端 UDP 埠連接(至少我知道)。但是在 .NET 對象的幫助下,可以藉助此腳本驗證遠端 SQL Server 瀏覽器的連接性,該腳本發送一個 UDP 1434 瀏覽器查詢(從網路跟踪反向工程)以獲取指定命名實例的資訊。

# verify UDP port 1434 connectivity and query SQL Server Browser for single instance

$hostNameOrIpAddress = "CMP0123456"
$instanceName = "ABC"

try
{

   Write-Host "Quering SQL Browser for host $hostNameOrIpAddress, instance $instanceName ..."

   $instanceNameBytes = [System.Text.Encoding]::ASCII.GetBytes($instanceName)
   $udpClient = New-Object Net.Sockets.UdpClient($hostNameOrIpAddress, 1434)
   $bufferLength = $InstanceNameBytes.Length + 2
   $browserQueryMessage = New-Object byte[] $bufferLength
   $browserQueryMessage[0] = 4
   $instanceNameBytes.CopyTo($browserQueryMessage, 1)
   $browserQueryMessage[$bufferLength-1] = 0
   $bytesSent = $udpClient.Send($browserQueryMessage, $browserQueryMessage.Length)
   $udpClient.Client.ReceiveTimeout = 10000
   $remoteEndPoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Broadcast, 0)
   $browserResponse = $udpClient.Receive([ref]$remoteEndPoint)
   Write-Host "SQL Server Browser response received" -ForegroundColor Green
   $payloadLength = $browserResponse.Length - 3
   $browserResponseString = [System.Text.ASCIIEncoding]::ASCII.GetString($browserResponse, 3, $payloadLength)
   Write-Host "SQL Server Browser raw datagram value: $browserResponseString"
   $elements = $browserResponseString.Split(";")
   $namedInstancePort = ""
   Write-Host  "SQL Server Browser parsed datagram:`r`n"
   for($i = 0; $i -lt $elements.Length; $i = $i + 2)
   {
       if ($elements[$i] -ne "")
       {
           Write-Host  "`t$($elements[$i])=$($elements[$i+1])"
           if($elements[$i] -eq "tcp")
           {
               $namedInstancePort = $elements[$i+1]
           }
       }
   }

}
catch [Exception]
{
   Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Yellow
}

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