我们的 5 个主数据库在单个可用性组中的物理(2 * 8 核,512GB,超线程)SQL Server 2016 SP2 Enterprise 上运行,有时我们会收到租约超时已过期的错误。我的理解是,如果租约无法更新,则存在系统范围的问题。
当我sp_server_diagnostics
在主副本的日志文件夹中检查(*SQLDIAG*.xel 文件)的输出时,在超时时间前后,我总是发现挂起的 IO 操作。
<ioSubsystem ioLatchTimeouts="0" intervalLongIos="0" totalLongIos="1">
<longestPendingRequests>
<pendingRequest duration="26566" filePath="\?\F:\SqlLogs\db1.ldf" offset="80824832" handle= "0x8d10" /> <pendingRequest duration="1987" filePath="\?\O:\SqlLogs\db2.ldf" offset="3880740352" handle="0x1330" /> <pendingRequest duration="1093" filePath="\ ?\O:\SqlLogs\db3.ldf" offset="288143360" handle="0x132c" /> <pendingRequest duration="974" filePath="\?\O:\SqlLogs\db3.ldf" offset="288145408" handle="0x132c" /> <pendingRequest duration="937" filePath="\?\O:\SqlLogs\db3.ldf"offset="288146944" handle="0x132c" />
</longestPendingRequests>
</ioSubsystem>
这是我在主副本的集群日志中找到的:
WARN [RES] SQL Server 可用性组:[hadrag] 无法检索数据列。返回代码 -1
ERR [RES] SQL Server 可用性组:[hadrag] 检测到故障,诊断检测信号丢失
ERR [RES] SQL Server 可用性组 <AG_Name>:[hadrag] 可用性组在给定的 HealthCheckTimeout 和 FailureConditionLevel
ERR [ RES] SQL Server 可用性组 <AG_Name>:[hadrag] 资源活动结果 0。
ERR [RES] SQL Server 可用性组:[hadrag] 检测到故障,诊断心跳丢失
ERR [RES] SQL Server 可用性组 <AG_Name>:[ hadrag] 可用性组在给定的 HealthCheckTimeout 和 FailureConditionLevel 情况下不健康
ERR [RES] SQL Server 可用性组 <AG_Name>:[hadrag] Resource Alive 结果 0。WARN
[RHS] Resource AG_Name IsAlive 指示失败。
这是 SQL Server 错误日志中的错误:
错误:19407,严重性:16,状态:1
SQL Server 托管可用性组“AG_Name”在租用超时期限内未收到来自 Windows Server 故障转移群集的进程事件信号。错误:19407,严重性:16,状态:1
可用性组“AG_Name”和 Windows Server 故障转移群集之间的租约已过期。SQL Server 实例与 Windows Server 故障转移群集之间出现连接问题。若要确定可用性组是否正确进行故障转移,请检查 Windows Server 故障转移群集中相应的可用性组资源。Always On:可用性组“AG_Name”的本地副本脱机,因为租约过期或租约续订失败。这只是一条信息性消息。无需用户操作。
这是来自的输出SELECT @@version
:
Microsoft SQL Server 2016 (SP2-CU15) (KB4577775) - 13.0.5850.14 (X64) Sep 17 2020 22:12:45 版权所有 (c) Microsoft Corporation Enterprise Edition:Windows Server 2012 R2 上基于内核的许可(64 位)标准 6.3(内部版本 9600:)
在我们的监控中,没有高 CPU 使用率的迹象。出现问题时也不会创建内存转储。
由于此超时,WSFC 服务重新启动集群资源“AG_Name”。之后,此资源重新启动,一切都再次完美运行。
我不明白的是:缓慢的 IO 请求如何导致租约超时?许多待处理的 IO 请求会导致租约超时吗?
不,缓慢的 I/O 请求不能直接导致租约超时。
但是,如果服务器完全过载(CPU 为 100%),则会导致挂起的 I/O 请求和租用超时。默认租用超时为 20 秒,而您的待处理 I/O 为 26 秒。高 CPU 或其他一些服务器/操作系统级别的问题更可能是这里的问题。
另一个原因是 SQL Server 遇到了一个严重错误,并且正在生成转储文件(这会导致进程暂停,可能足够长的时间让 WSFC 认为租约超时)。
有关更多可能性,请参阅文档:
您应该查看 SQL Server 错误日志以查看是否创建了转储。如果您从这些事件发生时开始进行监控,您还可以检查 CPU 是否已用尽。
在我们的监控工具中检查等待统计信息后,我注意到在问题发生的那一刻,有两种领先的等待类型,等待时间为 526000 毫秒/秒,PREEMPTIVE_SP_SERVER_DIAGNOSTICS和PREEMPTIVE_HADR_LEASE_MECHANISM。
如果我正确地解释了这一点,那么 PREEMPTIVE 部分意味着 SQLOS 之外的线程正在执行命令。在这种情况下,执行 SP_SERVER_DIAGNOSTICS 并更新租约。
高等待时间表明 SQL Server 正在等待这些线程完成。所以我认为这是操作系统没有响应的问题。
我们的系统管理员还提到,在超时的那一刻,系统日志中有几个event-id 153的警告:
所以我的结论是由于磁盘问题操作系统在定义的超时设置内没有响应并导致集群资源重新启动。