排查 SQL Server 连接问题的建议先决条件和清单

适用于: SQL Server
原始 KB 编号: 4009936

若要有效地排查连接问题,请收集以下信息:

  • 错误消息和错误代码的文本。 检查错误是否为间歇性错误, (仅在) 发生,还是) 始终发生一致的 (。

  • 来自 SQL Server 和客户端系统的应用程序和系统事件日志。 这些日志可帮助检查 SQL Server 上是否存在任何系统范围的问题。

  • 如果应用程序连接失败,请从应用程序收集连接字符串。 这些字符串通常位于 ASP.NET 应用程序的Web.config 文件中。

  • 收集和查看 SQL Server 错误日志以查找其他错误消息和异常。

  • 如果具有对 SQL Server 计算机的管理员访问权限,请使用以下过程收集和查看当前计算机设置和服务帐户:

    1. 下载最新版本的 SQLCHECK

    2. 将下载的文件解压缩到文件夹中,例如 C:\Temp

    3. 以管理员身份运行命令提示符,收集数据并保存到文件。 例如:SQLCHECK > C:\Temp\server01.SQLCHECK.TXT

    注意

    如果要对远程客户端的连接问题进行故障排除或对链接服务器查询进行故障排除,请在涉及的所有系统上运行 SQLCHECK 工具。

排查连接问题的快速清单

注意

以下部分可帮助你快速检查连接问题。 查看各个主题以获取详细的故障排除步骤。

选项 1

如果有权访问 “建议的先决条件 ”部分中提到的 SQLCHECK 工具的输出,并查看输出文件 (计算机、客户端安全性和 SQL Server) 的各个部分中的信息,请使用这些信息来解决导致问题的问题。 请参阅以下示例:

文件中的节 要搜索的文本 潜在操作 可帮助排查 (示例)
计算机信息 警告:网络驱动程序可能已过期 联机检查是否有新驱动程序。 各种连接错误
客户端安全和驱动程序信息 启用 Diffie-Hellman 密码套件。 如果客户端和服务器之间的算法版本不同,则可能有间歇性 TLS 失败的风险 如果遇到间歇性连接问题,请参阅 在 Windows 中连接到 SQL Server 时应用程序遇到强制关闭 TLS 连接错误 远程主机强制关闭现有连接
客户端安全和驱动程序信息 SQL 别名 如果存在,请确保别名配置正确,并指向正确的服务器和 IP 地址。 建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误
SQL Server 信息 感兴趣的服务 如果 SQL 服务未启动,请启动它。 如果在连接到命名实例时遇到问题,请确保 SQL Server Browser 服务已启动或尝试重启浏览器服务。 建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误
SQL Server 信息 域服务帐户属性 如果从 SQL Server 配置链接服务器,并且 Del 信任 值设置为 false,则链接服务器查询可能会遇到身份验证问题。 排查“用户登录失败”错误
SQL Server 信息 SPN 不存在 检查此表,查看 SQL Server 的 SPN 是否已正确配置并修复发现的任何问题。 无法生成 SSPI 上下文
SQL Server 信息 SQL Server 实例的详细信息 检查 TCP 已启用、TCP 端口等的值。 查看是否在服务器端启用了 TCP/IP,以及 SQL 默认实例是否正在侦听 1433 或其他端口。 各种连接错误

选项 2

如果无法在 SQL Server 计算机上运行 SQLCHECK,可以在进行深入故障排除之前检查以下项:

  1. 请确保 SQL Server 已启动,并在 SQL Server 错误日志中看到以下消息:

    SQL Server 现在已准备好进行客户端连接。 这是一条信息性消息;无需用户操作。

    在 PowerShell 中使用以下命令检查系统上 SQL Server 服务的状态:

    Get-Service | Where {$_.status -eq 'running' -and $_.DisplayName -match "sql server*"}
    

    使用以下命令在错误日志文件中搜索特定字符串“SQL Server 现在已准备好进行客户端连接。 这是一条信息性消息;无需执行任何用户操作。”:

    Get-ChildItem -Path "c:\program files\microsoft sql server\mssql*" -Recurse -Include Errorlog |select-string "SQL Server is now ready for client connections."
    
  2. 通过 IP 地址验证基本连接,并检查是否存在任何异常: ping -a <SQL Server machine>, ping -a <SQL Server IP address>。 如果发现任何问题,请与网络管理员协作。 或者,可以在 PowerShell 中使用 Test-NetConnection

    $servername = "DestinationServer"
    Test-NetConnection -ComputerName $servername
    
  3. 通过查看错误日志,检查 SQL Server 是否正在侦听适当的协议:

     Get-ChildItem -Path "c:\program files\microsoft sql server\mssql*" -Recurse -Include Errorlog |select-string "Server is listening on" , "ready to accept connection on" -AllMatches
    
  4. 检查是否能够使用 UDL 文件连接到 SQL Server。 如果有效,则连接字符串可能存在问题。 有关 UDL 测试过程的说明,请参阅 使用 UDL 文件测试 OLE DB 与 SQL Server 的连接。 或者,可以使用以下脚本创建和启动存储在 %TEMP% 文件夹) 中的 UDL-Test.udl 文件 (:

    clear
    
    $ServerName = "(local)"
    $UDL_String = "[oledb]`r`n; Everything after this line is an OLE DB initstring`r`nProvider=MSOLEDBSQL.1;Integrated Security=SSPI;Persist Security Info=False;User ID=`"`";Initial Catalog=`"`";Data Source=" + $ServerName + ";Initial File Name=`"`";Server SPN=`"`";Authentication=`"`";Access Token=`"`""
    
    Set-Content -Path ($env:temp + "\UDL-Test.udl") -Value $UDL_String -Encoding Unicode
    
    #open the UDL
    Invoke-Expression ($env:temp + "\UDL-Test.udl")
    
  5. 检查是否能够从其他客户端系统和不同的用户登录名连接到 SQL Server。 如果能够,问题可能特定于遇到问题的客户端或登录名。 检查有问题的客户端上的 Windows 事件日志以获取更多指针。 此外,请检查网络驱动程序是否是最新的。

  6. 如果遇到登录失败,请确保登录名 (服务器主体) 存在,并且它有权 CONNECT SQL 访问 SQL Server。 此外,请确保分配给登录名的默认数据库正确,并且映射的数据库主体对数据库具有 CONNECT 权限。 有关如何向数据库主体授予 CONNECT 权限的详细信息,请参阅 GRANT 数据库权限。 有关如何向服务器主体授予 CONNECT SQL 权限的详细信息,请参阅 GRANT 服务器权限。 使用以下脚本来帮助你识别这些权限:

    clear
    ## replace these variables with the login, user, database and server 
    $server_principal = "CONTOSO\JaneK"  
    $database_principal = "JaneK"
    $database_name = "mydb"
    $server_name = "myserver"
    
    Write-Host "`n******* Server Principal (login) permissions *******`n`n"
    sqlcmd -E -S $server_name -Q ("set nocount on; SELECT convert(varchar(32),pr.type_desc) as login_type, convert(varchar(32), pr.name) as login_name, is_disabled,
      convert(varchar(32), isnull (pe.state_desc, 'No permission statements')) AS state_desc, 
      convert(varchar(32), isnull (pe.permission_name, 'No permission statements')) AS permission_name,
      convert(varchar(32), default_database_name) as default_db_name
      FROM sys.server_principals AS pr
      LEFT OUTER JOIN sys.server_permissions AS pe
        ON pr.principal_id = pe.grantee_principal_id
      WHERE is_fixed_role = 0 -- Remove for SQL Server 2008
      and name = '" + $server_principal + "'")
    
    Write-Host "`n******* Database Principal (user) permissions *******`n`n"
    sqlcmd -E -S $server_name -d $database_name -Q ("set nocount on; SELECT convert(varchar(32),pr.type_desc) as user_type, convert(varchar(32),pr.name) as user_name, 
      convert(varchar(32), isnull (pe.state_desc, 'No permission statements')) AS state_desc, 
      convert(varchar(32), isnull (pe.permission_name, 'No permission statements')) AS permission_name 
      FROM sys.database_principals AS pr
      LEFT OUTER JOIN sys.database_permissions AS pe
        ON pr.principal_id = pe.grantee_principal_id
      WHERE pr.is_fixed_role = 0
      and name = '" + $database_principal + "'")
    
    Write-Host "`n******* Server to Database Principal mapping ********`n"
    sqlcmd -E -S $server_name -d $database_name -Q ("exec sp_helplogins '" + $server_principal + "'")
    
  7. 如果要排查 Kerberos 相关问题,可以使用 如何确定身份验证类型是否为 Kerberos 中的脚本。

常见的连接问题

完成先决条件和清单后,请参阅 常见连接问题 ,并选择相应的错误消息以获取详细的故障排除步骤。