排查 Azure SQL 数据库和 Azure SQL 托管实例的连接问题和其他问题

适用于: Azure SQL 数据库 Azure SQL 托管实例

与 Azure SQL 数据库或 Azure SQL 托管实例连接失败时,你会收到错误消息。

应用程序设计过程中始终应用最佳做法和设计准则。

注意

你可以使用 Azure SQL 连接性检查器来检测和修复 Azure SQL 数据库、Azure SQL 托管实例和 Azure Synapse Analytics 环境中的各种连接错误。

解决常见连接问题的步骤

  1. 确保已在应用程序服务器上启用 TCP/IP 作为客户端协议。 在未安装 SQL 工具的应用程序服务器上,运行 cliconfg.exe(SQL Server 客户端网络实用工具)来验证是否已启用 TCP/IP

  2. 检查应用程序的连接字符串,确保配置正确。 例如,确保连接字符串指定了正确的端口 (1433) 和完全限定的服务器名称。 请参阅使用 SQL Server Management Studio 获取连接信息

  3. 尝试增大连接超时值。 我们建议至少使用 30 秒连接超时。

  4. 使用 SQL Server Management Studio (SSMS)、UDL 文件、ping 或 telnet 来测试应用程序服务器与 Azure SQL 数据库之间的连接。 有关详细信息,请参阅排查连接问题连接问题的诊断

    注意

    作为故障排除步骤,还可以在不同的客户端计算机上测试连接。

  5. 最佳做法是,连接云的应用程序必须使用重试逻辑

如果这些步骤无法解决问题,请尝试收集更多的数据,然后联系支持人员。 如果应用程序是云服务,请启用日志记录。 此步骤会返回发生失败时的 UTC 时间戳。 有关如何启用日志记录的详细信息,请参阅为 Azure 应用服务中的应用启用诊断日志记录

实现重试逻辑

强烈建议客户端应用程序包含重试逻辑,以便它可以提供一段时间来让暂时性故障纠正自身,并尝试重建连接。 我们建议在第一次重试前延迟 5 秒钟。 如果在少于 5 秒的延迟后重试,云服务有超载的风险。 对于后续的每次重试,延迟应以指数级增大,最大值为 60 秒。

有关重试逻辑的代码示例,请参阅:

有关在应用程序中处理暂时性错误的更多信息,请查看排查 SQL 数据库的暂时性连接错误

连接池 (ADO.NET) 中提供了有关使用 ADO.NET 的客户端的阻塞期的说明。

暂时性故障错误消息(40197、40613 等)

Azure 基础结构能够在 SQL 数据库服务中出现大量工作负荷时动态地重新配置服务器。 此动态行为可能会导致客户端程序失去其与数据库或实例的连接。 此类错误情况称为 暂时性故障。 之所以会发生数据库重新配置事件是因为,有计划内事件(例如,软件升级)或计划外事件(例如,进程故障或负载均衡)。 大多数重新配置事件的生存期较短,应在最多 60 秒内完成。 但是,这些事件偶尔可能需要更长时间才能完成,例如当大型事务导致长时间运行的恢复时。 下表列出了在连接到 Azure SQL 数据库时应用程序可能会收到的各种暂时性错误。

暂时性故障错误代码的列表

错误代码 严重性 说明
926 14 Database 'replicatedmaster' cannot be opened. It has been marked SUSPECT by recovery. See the SQL Server error log for more information.

在最后的重新配置阶段,旧的主副本关闭其日志时,此错误可能在 SQL 托管实例错误日志上记录一段很短的时间。
MSSQL 错误文档中介绍了涉及此错误消息的其他非暂时性方案。
4060 16 Cannot open database "%.*ls" requested by the login. The login failed.

有关详细信息,请参阅错误 4000 到 4999
40197 17 The service has encountered an error processing your request. Please try again. Error code %d.

当服务由于软件或硬件升级、硬件故障或任何其他故障转移问题而关闭时,将收到此错误。 错误 40197 的消息中嵌入的错误代码 (%d) 提供有关所发生的故障或故障转移类型的其他信息。 错误 40197 的消息中嵌入的错误代码的一些示例有 40020、40143、40166 和 40540。

重新连接会将你自动连接到数据库的正常运行副本。 应用程序必须捕获错误 40197、记录该消息中嵌入的错误代码 (%d) 以供进行故障排除,然后尝试重新连接到 SQL 数据库,直到资源可用且再次建立连接为止。 有关详细信息,请参阅暂时性错误
40501 20 The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d.

有关详细信息,请参阅。
逻辑 SQL Server 资源限制
单一数据库的基于 DTU 的限制
弹性池的基于 DTU 的限制
单一数据库的基于 vCore 的限制
弹性池的基于 vCore 的限制
Azure SQL 托管实例资源限制
40613 17 Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them with the session tracing ID of '%.*ls'.

如果已建立到数据库的现有专用管理员连接 (DAC),则可能发生此错误。 有关详细信息,请参阅暂时性错误
49918 16 Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later.

有关详细信息,请参阅。
逻辑 SQL Server 资源限制
单一数据库的基于 DTU 的限制
弹性池的基于 DTU 的限制
单一数据库的基于 vCore 的限制
弹性池的基于 vCore 的限制
Azure SQL 托管实例资源限制
49919 16 Cannot process create or update request. Too many create or update operations in progress for subscription "%ld".

服务正忙于为订阅或服务器处理多个创建或更新请求。 为了优化资源,当前阻止了请求。 请查询 sys.dm_operation_status 以了解挂起的操作。 请等到挂起的创建或更新请求完成后,或删除其中一个挂起的请求,再重试请求。 如果操作似乎停滞,请等待其他正在进行的操作完成,或者在可行时取消操作。 例如,可以通过删除正在创建的数据库或副本来取消数据库副本或异地副本创建。 如果无法取消明显停滞的操作,请使用 Azure 开具支持工单
49920 16 Cannot process request. Too many operations in progress for subscription "%ld".

服务正忙于为此订阅处理多个请求。 为了优化资源,当前阻止了请求。 请查询 sys.dm_operation_status 以了解操作状态。 请等到挂起的请求完成,或删除其中一个挂起的请求,然后重试请求。 如果操作似乎停滞,请等待其他正在进行的操作完成,或者在可行时取消操作。 例如,可以通过删除正在创建的数据库或副本来取消数据库副本或异地副本创建。 如果无法取消明显停滞的操作,请使用 Azure 开具支持工单
4221 16 Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'.

副本不可用于登录,因为回收副本时缺少正在进行中的事务的行版本。 可以通过回滚或提交主要副本上的活动事务来解决此问题。 通过避免在主要副本上长时间写入事务,可以将此状况的发生次数降到最低。
615 21 Could not find database ID %d, name '%.*ls'

这意味着内存中缓存与 SQL 服务器实例不同步,并且 lookup 正在检索过时的数据库 ID。

SQL 登录使用内存中缓存来获取数据库名称到 ID 的映射。 缓存应与后端数据库同步,并在数据库与 SQL 服务器实例附加和分离时更新。
当分离工作流未能及时清理内存中缓存并且对数据库的后续查找指向过时数据库 ID 时,会收到此错误。

尝试重新连接到 SQL 数据库,直到资源可用,然后再次建立连接。 有关详细信息,请参阅暂时性错误

解决暂时性连接问题的步骤

  1. 检查 Azure 服务仪表板在应用程序报告期间是否发生任何已知的服务中断。
  2. 连接到云服务的应用程序(如 Azure SQL 数据库)应预期会有定期重新配置事件并实施重试逻辑来处理这些错误,而不是向用户呈现应用程序错误。
  3. 由于数据库即将达到其资源限制,因此错误看起来像是暂时性连接问题。 请参阅资源限制
  4. 如果连接问题继续存在,或者应用程序发生错误的持续时间超过 60 秒或在特定的一天中看到错误多次发生,请通过在 Azure 支持网站上选择“获取支持”提出 Azure 支持请求。

如果应用程序无法连接到服务器,则会出现此问题。

若要解决此问题,请尝试执行解决常见连接问题的步骤部分所述的步骤(按所述顺序执行)。

找不到或无法访问服务器/实例(错误 26、40、10053)

错误 26:查找指定的服务器时出错

System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections.(provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)

错误 40:无法与服务器建立连接

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

错误 10053:在接收来自服务器的结果时发生传输级错误

10053: A transport-level error has occurred when receiving results from the server. (Provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine)

如果应用程序无法连接到服务器,则会出现这些问题。

若要解决这些问题,请尝试执行解决常见连接问题的步骤部分所述的步骤(按所述顺序执行)。

由于防火墙问题而无法连接到服务器

错误 40615:无法连接到 <服务器名称>

若要解决此问题,请通过 Azure 门户在 SQL 数据库上配置防火墙设置

错误 5:无法连接到 <服务器名称>

若要解决此问题,请在客户端与 Internet 之间的所有防火墙上,确保为出站连接打开端口 1433。

无法登录到服务器(错误 18456、40531)

用户“<用户名>”登录失败

Login failed for user '<User name>'.This session has been assigned a tracing ID of '<Tracing ID>'. Provide this tracing ID to customer support when you need assistance. (Microsoft SQL Server, Error: 18456)

若要解决此问题,请让服务管理员为你提供有效的用户名和密码。

服务管理员通常可使用以下步骤添加登录凭据:

  1. 使用 SQL Server Management Studio (SSMS) 登录到服务器。

  2. 要检查是否已禁用该登录名,请在 master 数据库中运行以下 SQL 查询:

    SELECT name, is_disabled FROM sys.sql_logins;
    
  3. 如果禁用了相应的名称,可能会决定使用以下语句来启用它:

    ALTER LOGIN <User name> ENABLE;
    
  4. 如果 SQL 登录用户名不存在,请编辑并运行以下 SQL 查询,以创建新的 SQL 登录名:

    CREATE LOGIN <SQL_login_name, sysname, login_name>
    WITH PASSWORD = '<password, sysname, Change_Password>';
    GO
    
  5. 在“SSMS 对象资源管理器”中,展开“数据库”。

  6. 选择要授予用户权限的数据库。

  7. 右键单击“安全性”,然后选择“新建”、“用户” 。

  8. 在带有占位符的生成的脚本中,按照复制 SSMS 模板参数的步骤操作,并执行它:

    CREATE USER [<user_name, sysname, user_name>]
    FOR LOGIN [<login_name, sysname, login_name>]
    WITH DEFAULT_SCHEMA = [<default_schema, sysname, dbo>];
    GO
    
    -- Add user to the database owner role
    EXEC sp_addrolemember N'db_owner', N'<user_name, sysname, user_name>';
    GO
    

    也可使用 sp_addrolemember 将特定的用户映射到特定的数据库角色。

    注意

    在 Azure SQL 数据库中,考虑使用更新的 ALTER ROLE 语法来管理数据库角色成员身份。

有关详细信息,请参阅在 Azure SQL 数据库中管理数据库和登录名

连接超时过期错误

System.Data.SqlClient.SqlException (0x80131904):连接超时过期

System.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired. The timeout period elapsed while attempting to consume the pre-login handshake acknowledgement. This could be because the pre-login handshake failed or the server was unable to respond back in time. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=3; handshake=29995;

System.Data.SqlClient.SqlException (0x80131904):超时过期

System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

System.Data.Entity.Core.EntityException:基础提供程序在打开时失败

System.Data.Entity.Core.EntityException: The underlying provider failed on Open. -> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. -> System.ComponentModel.Win32Exception: The wait operation timed out

无法连接到 <服务器名称>

Cannot connect to <server name>.ADDITIONAL INFORMATION:Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=231; handshake=983; [Login] initialization=0; authentication=0; [Post-Login] complete=13000; (Microsoft SQL Server, Error: -2) For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft%20SQL%20Server&EvtSrc=MSSQLServer&EvtID=-2&LinkId=20476 The wait operation timed out

这些异常可能是连接或查询问题造成的。 要确认此错误是否由连接问题造成,请参阅确认错误是否由连接问题造成

发生连接超时的原因是应用程序无法连接到服务器。 若要解决此问题,请尝试执行解决常见连接问题的步骤部分所述的步骤(按所述顺序执行)。

网络连接终止错误

SQL 客户端库使用 TCP 网络协议连接到 Azure SQL 数据库和 Azure SQL 托管实例。 客户端库使用名为 TCP 提供程序的较低级别组件来管理 TCP 连接。 当 TCP 提供程序检测到远程主机意外终止了现有 TCP 连接时,客户端库将引发错误。 由于该错误是客户端错误,而不是 SQL Server 错误,因此不包含 SQL 错误号。 而是错误号为 0,并使用来自 TCP 提供程序的错误消息。

网络连接终止错误的示例包括:

A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) An existing connection was forcibly closed by the remote host

A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

The client was unable to establish a connection because of an error during connection initialization process before login. Possible causes include the following: the client tried to connect to an unsupported version of SQL Server; the server was too busy to accept new connections; or there was a resource limitation (insufficient memory or maximum allowed connections) on the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

由于数据库或弹性池暂时不可用,可能会发生连接终止错误。 由于数据库服务器和客户端应用程序之间的网络基础结构中存在各种问题(包括防火墙、网络设备等),也可能发生这些错误。这些问题可能是暂时性的,也可能是永久性的。 作为一般指导,应用程序应在将这些错误视为永久失败之前,对这些错误使用固定次数的重试尝试。

资源调控错误

Azure SQL 数据库使用基于资源调控器的资源治理实现来强制实施资源限制。 详细了解 Azure SQL 数据库中的资源管理

首先列出最常见的资源治理错误及其详细信息,然后是资源治理错误消息表。

错误 10928 和 10936:资源 ID:1。 [数据库或弹性池] 的请求限制为 %d,现已达到该限制

如果达到数据库级别限制,则本例中的详细错误消息如下:Resource ID : 1. The request limit for the database is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.

如果达到弹性池限制,则此情况下的详细错误消息如下:Resource ID : 1. The request limit for the elastic pool is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance. 弹性池限制高于数据库限制,有关详细信息,请参阅资源限制。 当池中的多个数据库同时使用某个资源(例如辅助角色)时,可能会遇到限制。

此错误消息指示已达到数据库或弹性池的辅助角色限制。 数据库或弹性池的服务目标的最大并发辅助角色值将存在,而不是占位符 %d。

注意

Azure SQL 数据库的初始产品/服务仅支持单线程查询。 当时的请求数量通常等于工作线程数量。 为了后向兼容性,Azure SQL 数据库中的错误消息 10928 和 10936 包含措辞“[...] 的请求限制为 N,现已达到该限制”。 达到的实际是作线程的数量限制。 如果最大并行度 (MAXDOP) 设置等于零或大于 1,则辅助角色数可能远高于请求数,并且可能比 MAXDOP 等于 1 时更快达到限制。

详细了解会话、工作线程和请求

如果需要,使用专用管理员连接 (DAC) 进行连接

如果在达到工作线程限制的情况下正在进行实时事件,则在使用 SQL Server Management Studio (SSMS) 或 Azure Data Studio 连接时可能会收到错误 10928。 即使已达到最大工作线程阈值,一个会话也可以使用用于数据库管理员的诊断连接 (DAC) 进行连接。

要从 SSMS 建立与 DAC 的连接:

  • 从菜单中,选择“文件”“新建”>“数据库引擎查询”
  • 从连接对话框的“服务器名称”字段中,输入 admin:<fully_qualified_server_name>(例如,admin:servername.database.chinacloudapi.cn)。
  • 选择“选项
  • 选择“连接属性”选项卡
  • 在“连接到数据库:”框中,键入数据库的名称
  • 选择“连接” 。

如果您收到错误 40613 Database '%.&#x2a;ls' on server '%.&#x2a;ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.&#x2a;ls',这可能表示另一个会话已连接到 DAC。 一次只能有一个会话连接到单一数据库或弹性池的 DAC。

如果在选择“连接”后遇到错误“连接到服务器失败”,若是你使用的是 SSMS 18.9 之前的版本,则可能仍然成功建立了 DAC 会话。 SSMS 的早期版本试图提供 Intellisense 与 DAC 的连接。 但失败了,因为 DAC 只支持一个工作线程,而 Intellisense 需要一个单独的工作线程。

在 SSMS 中不能将 DAC 连接与对象资源管理器一起使用。

查看 max_worker_percent 使用情况

要查找数据库 14 天的资源消耗统计信息,请查询 sys.resource_stats 系统目录视图。 max_worker_percent 列显示已使用的工作线程相对于数据库的工作线程限制的百分比。 连接到你的逻辑服务器上的 master 数据库以查询 sys.resource_stats

SELECT start_time, end_time, database_name, sku, avg_cpu_percent, max_worker_percent, max_session_percent 
FROM sys.resource_stats;

您还可以从 sys.dm_db_resource_stats 动态管理视图中查询过去一小时内的资源消耗统计信息。 直接连接到您的数据库查询 sys.dm_db_resource_stats

SELECT end_time, avg_cpu_percent, max_worker_percent, max_session_percent
FROM sys.dm_db_resource_stats;

尽可能降低工作线程使用率

链阻塞会导致数据库中工作线程数量的激增。 大量的并发并行查询可能会导致大量的工作线程。 提高最大并行度 (MAXDOP) 或将 MAXDOP 设置为零都可以增加活动工作线程的数量。

按照以下步骤对工作线程不足的事件进行会审:

  1. 调查是否正在发生阻塞,或者你是否可以确定大量并发工作线程。 数据库返回错误 10928 时,请运行以下查询以检查当前请求并检查是否发生阻塞。 您可能需要使用专用管理员连接 (DAC) 进行连接才能执行该查询。

    SELECT
        r.session_id, r.request_id, r.blocking_session_id, r.start_time, 
        r.status, r.command, DB_NAME(r.database_id) AS database_name,
        (SELECT COUNT(*) 
            FROM sys.dm_os_tasks AS t 
            WHERE t.session_id=r.session_id and t.request_id=r.request_id) AS worker_count,
        i.parameters, i.event_info AS input_buffer,
        r.last_wait_type, r.open_transaction_count, r.total_elapsed_time, r.cpu_time,
        r.logical_reads, r.writes, s.login_time, s.login_name, s.program_name, s.host_name
    FROM sys.dm_exec_requests as r
    JOIN sys.dm_exec_sessions as s on r.session_id=s.session_id
    OUTER APPLY sys.dm_exec_input_buffer (r.session_id,r.request_id) AS i
    WHERE s.is_user_process=1;
    GO
    
    1. 查找包含 blocking_session_id 的行,以确定阻塞的会话。 在列表中查找每个 blocking_session_id,以确定该会话是否也发生阻塞。 遵循 blocking_session_idsession_id 值最终将你转到头阻止程序:未阻止但正在阻止的会话。 优化最前面的阻塞查询。

      提示

      有关对长期运行的查询或阻塞的查询进行故障排除的详细信息,请参阅了解并解决 Azure SQL 数据库的阻塞问题

    2. 要识别大量并发工作线程,请查看总体请求数和每个请求的 worker_count 列。 Worker_count 是采样时的工作线程数量,并且可能随着请求的执行不断变化。 如果增加工作线程的原因是为了以最佳并行度运行的并发查询,则调整查询以降低资源利用率。 有关详细信息,请参阅查询优化/提示

  2. 评估数据库的最大并行度 (MAXDOP) 设置。

提高工作线程上限

如果即使解决了阻塞、优化了查询并验证了 MAXDOP 设置,但数据库或弹性池始终达到其辅助角色限制,请考虑纵向扩展数据库或弹性池以提高辅助角色上限。

根据服务层和计算大小,查找 Azure SQL 数据库的资源限制:

详细了解工作线程的 Azure SQL 数据库资源治理

错误 10929:资源 ID:1

10929: Resource ID: 1. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. See http://go.microsoft.com/fwlink/?LinkId=267637 for assistance. Otherwise, please try again later.

错误 40501:服务当前繁忙

40501: The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d.

错误 40501 是一个引擎限制错误,表示超过了资源限制。

有关资源限制的更多信息,请参阅逻辑 SQL 服务器资源限制

错误 40544:数据库已达到其大小配额

40544: The database has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions. Incident ID: <ID>. Code: <code>.

当数据库达到其大小配额时会发生此错误。

以下步骤可帮助你解决此问题,或提供更多的选项:

  1. 使用 Azure 门户中的仪表板检查数据库的当前大小。

    注意

    若要识别哪些表消耗了最多的空间,因此确定可能需要清理哪些表,请运行以下 SQL 查询:

    SELECT o.name,
     SUM(p.row_count) AS 'Row Count',
     SUM(p.reserved_page_count) * 8.0 / 1024 AS 'Table Size (MB)'
    FROM sys.objects o
    JOIN sys.dm_db_partition_stats p on p.object_id = o.object_id
    GROUP BY o.name
    ORDER BY [Table Size (MB)] DESC;
    GO
    
  2. 如果当前大小未超过所用版本支持的最大大小,你可以使用 ALTER DATABASE 来增大 MAXSIZE 设置。

  3. 如果数据库已超过所用版本支持的最大大小,请尝试以下一个或多个步骤:

    • 执行一般的数据库清理活动。 例如,使用截断/删除操作清理不需要的数据,或者使用 SQL Server Integration Services (SSIS) 或批量复制程序 (bcp) 实用工具移出数据。
    • 请将数据分区或删除、删除索引或查阅文档以找到可能的解决方案。
    • 有关数据库缩放的信息,请参阅缩放单一数据库资源缩放弹性池资源

错误 40549:存在长时间运行的事务,因此已终止会话

40549: Session is terminated because you have a long-running transaction. Try shortening your transaction.

如果反复出现此错误,请尝试执行以下步骤来解决问题:

  1. 运行以下查询,看看任何打开的会话中的 duration_ms 列是否具有较高的值:

    SELECT
        r.start_time, DATEDIFF(ms,start_time, SYSDATETIME()) as duration_ms, 
        r.session_id, r.request_id, r.blocking_session_id,  
        r.status, r.command, DB_NAME(r.database_id) AS database_name,
        i.parameters, i.event_info AS input_buffer,
        r.last_wait_type, r.open_transaction_count, r.total_elapsed_time, r.cpu_time,
        r.logical_reads, r.writes, s.login_time, s.login_name, s.program_name, s.host_name
    FROM sys.dm_exec_requests as r
    JOIN sys.dm_exec_sessions as s on r.session_id=s.session_id
    OUTER APPLY sys.dm_exec_input_buffer (r.session_id,r.request_id) AS i
    WHERE s.is_user_process=1
    ORDER BY start_time ASC;
    GO
    

    你可以忽略其 input_buffer 列显示从 sys.fn_MSxe_read_event_stream 读取的查询的行:这些请求与扩展事件会话相关。

  2. 查看 blocking_session_id 列以查看阻塞是否会导致事务长时间运行。

    注意

    有关故障排除 Azure SQL 数据库中阻塞的详细信息,请参阅了解并解决 Azure SQL 数据库阻塞问题

  3. 请考虑批量处理查询。 有关批处理的信息,请参阅如何使用批处理来改善 SQL 数据库应用程序的性能

错误 40551:由于过度使用 tempdb,已终止会话

40551: The session has been terminated because of excessive TEMPDB usage. Try modifying your query to reduce the temporary table space usage.

若要解决此问题,请执行以下步骤:

  1. 更改查询以减少临时表空间的用量。
  2. 删除不再需要的临时对象。
  3. 截断表,或删除未使用的表。

错误 40552:由于过度使用事务日志空间,已终止会话

40552: The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.

若要解决此问题,请尝试执行以下方法:

错误 40553:由于过度使用 内存,已终止会话

40553: The session has been terminated because of excessive memory usage. Try modifying your query to process fewer rows.

若要解决此问题,请尝试优化查询。

有关详细的故障排除过程,请参阅我的查询是否在云中正常运行?

有关其他内存不足错误和示例查询的详细信息,请参阅排查 Azure SQL 数据库的内存不足错误

资源管理错误消息表

错误代码 严重性 说明
10928 20 Resource ID: %d. The %s limit for the database is %d and has been reached. See 'http://docs.azure.cn/azure-sql/database/resource-limits-logical-server' for assistance.

资源 ID 指示已达到限制的资源。 当资源 ID = 1 时,表示已达到工作进程限制。 在错误“10928: 资源 ID: 1. 数据库的请求限制是 %d,现已达到该限制”中了解详细信息。当资源 ID = 2 时,这表示已经达到了会话限制。

详细了解资源限制:
逻辑 SQL Server 资源限制
单一数据库的基于 DTU 的限制
单一数据库的基于 vCore 的限制
Azure SQL 托管实例资源限制
10936 20 Resource ID: %d. The %s limit for the elastic pool is %d and has been reached. See 'http://docs.azure.cn/azure-sql/database/resource-limits-logical-server' for assistance.

资源 ID 指示已达到限制的资源。 当资源 ID = 1 时,表示已达到工作进程限制。 详细了解错误 10936:资源 ID:1。弹性池的请求限制是 %d,现已达到该限制。。 当资源 ID = 2 时,这表示已达到会话限制。

详细了解资源限制:
逻辑 SQL Server 资源限制
弹性池的基于 DTU 的限制
弹性池的基于 vCore 的限制
Azure SQL 托管实例资源限制
10929 20 Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database.

资源 ID 指示已达到限制的资源。 对于工作线程,资源 ID = 1。 对于会话,资源 ID = 2。 有关详细信息,请参阅。
逻辑 SQL Server 资源限制
单一数据库的基于 DTU 的限制
弹性池的基于 DTU 的限制
单一数据库的基于 vCore 的限制
弹性池的基于 vCore 的限制
Azure SQL 托管实例资源限制
否则,请稍后重试。
40544 20 The database has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions.

有关数据库缩放的信息,请参阅缩放单一数据库资源缩放弹性池资源
40549 16 Session is terminated because you have a long-running transaction. Try shortening your transaction.

有关批处理的信息,请参阅如何使用批处理来改善 SQL 数据库应用程序的性能
40550 16 The session has been terminated because it has acquired too many locks. Try reading or modifying fewer rows in a single transaction.

有关批处理的信息,请参阅如何使用批处理来改善 SQL 数据库应用程序的性能
40551 16 The session has been terminated because of excessive tempdb usage. Try modifying your query to reduce the temporary table space usage.

如果在使用临时对象,则通过在会话不再需要临时对象后删除这些临时对象,可以节省 tempdb 数据库中的空间。 要详细了解 SQL 数据库中的 tempdb 限制,请参阅 SQL 数据库中的 Tempdb 数据库
40552 16 The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.

有关批处理的信息,请参阅如何使用批处理来改善 SQL 数据库应用程序的性能

如果在使用 bcp.exe 实用程序或 System.Data.SqlClient.SqlBulkCopy 类执行大容量插入,则可尝试使用 -b batchsizeBatchSize 选项来限制在各事务中复制到服务器的行数。 如果正在使用 ALTER INDEX 语句重新生成索引,请尝试使用 REBUILD WITH ONLINE = ON 选项。 有关 vCore 购买模型事务日志大小的信息,请参阅:
单一数据库的基于 vCore 的限制
弹性池的基于 vCore 的限制
Azure SQL 托管实例资源限制
40553 16 The session has been terminated because of excessive memory usage. Try modifying your query to process fewer rows.

在 Transact-SQL 代码中减少 ORDER BYGROUP BY 操作的数目可以降低查询的内存需求。 有关数据库缩放的信息,请参阅缩放单一数据库资源缩放弹性池资源。 有关内存不足错误和示例查询的详细信息,请参阅排查 Azure SQL 数据库的内存不足错误

弹性池错误

以下错误与创建和使用弹性池有关:

错误代码 严重性 说明 纠正措施
1132 17 The elastic pool has reached its storage limit. The storage usage for the elastic pool cannot exceed (%d) MBs.

到达弹性池的存储限制时,尝试向数据库写入数据。 有关资源限制的信息,请参阅:
弹性池的基于 DTU 的限制
弹性池的基于 vCore 的限制
在可能的情况下,考虑增加弹性池的 DTU 数并/或将存储添加到弹性池,以便提高其存储限制、减少弹性池中各数据库使用的存储,或者从弹性池中删除数据库。 有关弹性池缩放的信息,请参阅缩放弹性池资源。 有关从数据库中删除未使用的空间的详细信息,请参阅管理 Azure SQL 数据库中数据库的文件空间
10929 16 The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database.

有关资源限制的信息,请参阅:
弹性池的基于 DTU 的限制
弹性池的基于 vCore 的限制
否则,请稍后重试。 每个数据库的 DTU/vCore 最小值;每个数据库的 DTU/vCore 最大值。 弹性池中所有数据库上尝试的并发工作进程总数超过池限制。
在可能的情况下,考虑增加弹性池的 DTU 数或 vCores 数,以便提高其辅助角色限制,或者从弹性池中删除数据库。
40844 16 Database '%ls' on Server '%ls' is a '%ls' edition database in an elastic pool and cannot have a continuous copy relationship. 空值
40857 16 Elastic pool not found for server: '%ls', elastic pool name: '%ls'. Specified elastic pool does not exist in the specified server. 提供有效的弹性池名称。
40858 16 Elastic pool '%ls' already exists in server: '%ls'. Specified elastic pool already exists in the specified server. 提供新弹性池名称。
40859 16 Elastic pool does not support service tier '%ls'. Specified service tier is not supported for elastic pool provisioning. 提供正确的版本,或者将服务层级留空以使用默认服务层级。
40860 16 Elastic pool '%ls' and service objective '%ls' combination is invalid. Elastic pool and service tier can be specified together only if resource type is specified as 'ElasticPool'. 指定正确的弹性池和服务层级组合。
40861 16 The database edition '%.*ls' cannot be different than the elastic pool service tier which is '%.*ls'. The database edition is different than the elastic pool service tier. 请勿指定不同于弹性池服务层级的数据库版本。 数据库版本不需要指定。
40862 16 Elastic pool name must be specified if the elastic pool service objective is specified. Elastic pool service objective does not uniquely identify an elastic pool. 如果使用弹性池服务目标,则指定弹性池名称。
40864 16 The DTUs for the elastic pool must be at least (%d) DTUs for service tier '%.*ls'. Attempting to set the DTUs for the elastic pool below the minimum limit. 重新尝试将弹性池的 DTU 数至少设置为最小限制。
40865 16 The DTUs for the elastic pool cannot exceed (%d) DTUs for service tier '%.*ls'. Attempting to set the DTUs for the elastic pool above the maximum limit. 重新尝试将弹性池的 DTU 数设置为不超过最大限制。
40867 16 The DTU max per database must be at least (%d) for service tier '%.*ls'. Attempting to set the DTU max per database below the supported limit. 考虑使用支持所需设置的弹性池服务层级。
40868 16 The DTU max per database cannot exceed (%d) for service tier '%.*ls'. Attempting to set the DTU max per database beyond the supported limit. 考虑使用支持所需设置的弹性池服务层级。
40870 16 The DTU min per database cannot exceed (%d) for service tier '%.*ls'. Attempting to set the DTU min per database beyond the supported limit. 考虑使用支持所需设置的弹性池服务层级。
40873 16 The number of databases (%d) and DTU min per database (%d) cannot exceed the DTUs of the elastic pool (%d). Attempting to specify DTU min for databases in the elastic pool that exceeds the DTUs of the elastic pool. 考虑增加弹性池的 DTU 数,或者降低每个数据库的 DTU 最小值,或者降低弹性池中数据库的数目。
40877 16 An elastic pool cannot be deleted unless it does not contain any databases. The elastic pool contains one or more databases and therefore cannot be deleted. 删除弹性池中的数据库,以便删除弹性池。
40881 16 The elastic pool '%.*ls' has reached its database count limit. The database count limit for the elastic pool cannot exceed (%d) for an elastic pool with (%d) DTUs. Attempting to create or add database to elastic pool when the database count limit of the elastic pool has been reached. 在可能的情况下,考虑增加弹性池的 DTU 数,以便提高其数据库限制,或者从弹性池中删除数据库。
40889 16 The DTUs or storage limit for the elastic pool '%.*ls' cannot be decreased since that would not provide sufficient storage space for its databases. Attempting to decrease the storage limit of the elastic pool below its storage usage. 考虑降低弹性池中各个数据库的存储使用量,或者从池中删除数据库以降低其 DTU 数或存储限制。
40891 16 The DTU min per database (%d) cannot exceed the DTU max per database (%d). Attempting to set the DTU min per database higher than the DTU max per database. 确保每个数据库的 DTU 最小值不超过每个数据库的 DTU 最大值。
TBD 16 The storage size for an individual database in an elastic pool cannot exceed the max size allowed by '%.*ls' service tier elastic pool. The max size for the database exceeds the max size allowed by the elastic pool service tier. 将数据库的最大大小设置为处于弹性池服务层级允许的最大大小限制范围内。

无法打开登录名请求的数据库 "master"。 登录失败

发生此问题的原因是帐户无权访问 master 数据库。 但在默认情况下,SQL Server Management Studio (SSMS) 会尝试连接到 master 数据库。

若要解决此问题,请执行以下步骤:

  1. 在 SSMS 的登录屏幕上选择“选项”,然后选择“连接属性”。

  2. 在“连接到数据库”字段中,输入用户的默认数据库名称作为默认登录数据库,然后选择“连接” 。

    SSMS 中的连接对话框的屏幕截图,其中显示了“连接属性”选项卡。

只读错误

如果尝试向一个处于只读状态的数据库写入,会收到错误消息。 在某些情况下,数据库处于只读状态的原因可能不会立即明了。

错误 3906:无法更新数据库 "databaseName",因为数据库是只读的。

尝试修改一个处于只读状态的数据库时,将产生以下错误。

Msg 3906, Level 16, State 2, Line 1
Failed to update database "%d" because the database is read-only.

对于数据库为只读状态的原因,有多种可能的解释。

手动故障转移后,应用程序仍在连接到旧副本

在 Azure SQL 数据库中,故障转移到另一个副本后,应用程序可能会由于 DNS 而仍在连接以前的主要副本。 故障转移组连接路由使用 DNS 实现。

可能的根本原因:

  1. 在故障转移期间,故障转移组端点会进行更新,以通过更改相应 DNS 条目的目标,指向相应的新主服务器和新辅助服务器。 默认情况下,创建 DNS 条目时 TTL 为 30 秒,这意味着 DNS 客户端将这些条目缓存 30 秒。 因此,对 DNS 记录的更新不会立即传播;条目直到所有客户端和中间节点刷新其缓存后才会过时。 因此,在故障转移后,路由登录到故障转移组端点的操作可能需要 0 到大约 10 分钟(具体取决于网络拓扑)。 刷新 DNS 缓存可能会也可能无法解决问题,因为响应 DNS 请求的中间网络节点也会缓存 DNS 结果一段时间。

    此问题的建议解决方法是等到客户端上刷新了 DNS 条目。 目前,此解决方法导致的问题可在 10 分钟内自行解决。

  2. 有些 SQL 客户端库使用名为“连接池”的功能,该功能可重复使用与同一数据源的连接,而不是关闭并在需要时重新打开它们。 尤其是,默认情况下在 ADO.NET 中启用连接池。 与 1) 中描述的问题组合时,连接池可能会导致新打开的连接重复使用与旧数据库的连接,因而阻止应用程序无限期地连接到新的主数据库。

解决方案:

故障转移组故障转移后,此 DNS 问题有三种可能的解决方法:

  1. 修改应用程序以在每次遇到“只读”错误时调用 SQLConnection.ClearAllPoolsSQLConnection.ClearPool(conn)
  2. 在应用程序连接字符串中,指定 Pooling=False 以禁用连接池。 这应经过测试,因为如果应用程序经常打开和关闭连接,则可能会影响性能。
  3. 另一种避免 DNS 复制/缓存延迟的选项是在遇到 3906 之后的时间范围内使用(原始辅助服务器、现在为新主服务器的)Azure SQL 数据库逻辑服务器名称直接连接。

你可能已连接到只读副本

对于 Azure SQL 数据库和 Azure SQL 托管实例,你可以连接到只读副本上的数据库。 在本例中,使用 DATABASEPROPERTYEX() 函数的以下查询将返回 READ_ONLY

SELECT DATABASEPROPERTYEX(DB_NAME(), 'Updateability');
GO

如果要使用 SQL Server Management Studio 进行连接,请验证是否已在“其他连接参数”选项卡中(连接选项上)指定了 ApplicationIntent=ReadOnly

如果是使用连接字符串从应用程序或客户端进行连接,请验证连接字符串是否指定了 ApplicationIntent=ReadOnly。 有关详细信息,请参阅连接只读副本

数据库可能被设置为只读

如果你使用的是 Azure SQL 数据库,则数据库本身可能已被设置为只读。 可以通过以下查询来验证数据库的状态:

SELECT name, is_read_only
FROM sys.databases
WHERE database_id = DB_ID();

可以使用 ALTER DATABASE Transact-SQL 在 Azure SQL 数据库中修改数据库的只读状态。 目前不能将托管实例中的数据库设置为只读。

确认错误是否由连接问题造成

若要确认某个错误是否由连接问题造成,请查看帧的堆栈跟踪,其中会显示打开连接的调用,如下所示(请注意对 SqlConnection 类的引用):

System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
 at System.Data.SqlClient.SqlConnection.Open()
 at AzureConnectionTest.Program.Main(String[] args)
ClientConnectionId:<Client connection ID>

如果异常是由查询问题触发的,则你会看到如下所示的调用堆栈(请注意对 SqlCommand 类的引用)。 对于这种情况,请优化查询

  at System.Data.SqlClient.SqlCommand.ExecuteReader()
  at AzureConnectionTest.Program.Main(String[] args)
  ClientConnectionId:<Client ID>

有关微调性能的更多信息,请参阅以下资源: