我们有一个可用性组,由 42 个数据库组成,其中一个为同步副本,另一个为异步副本。同步副本能够跟上主副本(根据定义),但异步副本中的大多数数据库在工作日开始时会冻结其进度,直到工作日结束前都不会取得进展。以下图表显示了数据库的 AG 滞后,由last_commit_time
sys.dm_hadr_database_replica_states计算得出
对于大多数数据库来说,该last_commit_time
时间大约在上午 9:00 左右,直到工作日结束。以下引述来自故障排除:异步提交可用性组副本可能带来的数据丢失
以下部分介绍了异步提交辅助副本可能出现高数据丢失风险的常见原因,假设您的服务器实例中没有与可用性组无关的系统性性能问题。
网络延迟高或网络吞吐量低导致主副本上日志累积
磁盘 I/O 瓶颈减慢了辅助副本上的日志强化
大约一半的数据库使用Microsoft Azure 中的 SQL Server 数据文件功能。这些数据库的 I/O 性能非常差,以至于我有时会在错误日志中看到 15 秒的 I/O 警告。让我感到困惑的是,大多数延迟最严重的数据库都不在 Azure 存储上。我能看到的唯一模式是,具有最佳 I/O 性能的数据库似乎具有最大的延迟。
如果可用性组中有多个数据库,那么一个 I/O 性能较差的数据库是否可能导致另一个 I/O 性能良好的数据库滞后?
如果需要的话,请提供一些有关我的情况的额外技术细节:
SQL Server 版本是 Microsoft SQL Server 2019 (RTM-CU30)。
托管异步副本的数据中心距离主数据中心 1800 英里。两个数据中心都在美国。
从异步副本到主副本的 Ping 时间为 40-50 毫秒。我多次被告知,我们没有达到某种整体网络吞吐量限制。netttcp 测试显示带宽容量为 25-30Mbit/秒。
根据
hadr_database_flow_control_action
扩展事件,工作日内未取得进展的数据库实际上 100% 的时间都在等待流量控制。滞后较少的数据库无需花时间等待流量控制。根据
hadr_transport_flow_control_action
扩展事件,传输层上没有任何等待流量控制的情况。Sends to Transport/sec
性能计数器似乎证实了这一点。跟踪标志 12310 无论如何都已启用并且没有明显的效果。
对于存储在 Azure 之外的异步数据库,写入延迟在 1-10 毫秒之间。对于存储在 Azure 中的数据库,写入延迟高达 400 毫秒。
使用
Bytes Sent to Replica/sec
perfmon 计数器,异步副本能够保持到上午 8:30 左右。然后它就落后了,只有在几个小时后出现一些巨大的进展后才能赶上。
- perfmon计数器
Log Bytes Flushed/sec
(一天中部分时间的数据丢失)似乎与我们看到的发送字节数相符。最终用户活动在下午 4:30 左右开始下降,此时异步副本在追赶方面取得了更多进展。
- 我于 2025 年 2 月 6 日生成了一份 AG 延迟报告,瓶颈在于主服务器上的发送和流量控制。我不知道如何跟进这些结果:
- 我知道将使用 Microsoft Azure 中的 SQL Server 数据文件功能的数据库放入异步 AG 可能是一种不寻常的设置。我们有效地将数据发送到 1800 英里外只是为了将其发送到云端。微软关于该功能的文档表明这可能没有必要:
高可用性和灾难恢复优势:使用 Microsoft Azure 中的 SQL Server 数据文件功能可能会简化高可用性和灾难恢复解决方案。例如,如果 Microsoft Azure 中的虚拟机或 SQL Server 实例崩溃,您只需重新建立与 blob 的链接即可在新的 SQL Server 实例中重新创建数据库。
我再次运行了 AGLatency 报告工具,并收集了十分钟的数据。对同步提交 AlwaysOn 可用性组之间的数据移动延迟进行故障排除描述了如何计算网络延迟:
我认为
hadr_lsn_send_complete->primary:hadr_receive_harden_lsn_message
异步副本不会执行此步骤。我自己进行了数据处理,比较了primary:hadr_log_block_send_complete
和的扩展事件日志时间戳secondary:hadr_transport_receive_log_block_message
。以下是按数据库汇总的结果,数据库名称替换为存储是否在 Azure 中:数据按主副本中的事件数排序
hadr_log_block_send_complete
。请注意,计算出的延迟sys.dm_hadr_database_replica_states
与事件数非常吻合hadr_log_block_send_complete
。延迟最严重的数据库向异步副本发送的日志块最多。此外,观察到的延迟计算非常糟糕。辅助副本平均需要 15 秒才能收到日志块!我使用非默认设置运行了 ping,也观察到了问题:我目前的理论是,AG 延迟是由高网络延迟而不是糟糕的 I/O 性能引起的。托管在性能不佳的 Azure 存储上的数据库恰好每秒的事务数低于其他数据库。这就是为什么它们的延迟较少,尽管它们的 I/O 性能如此糟糕。也许存在某种共享网络资源,导致工作时间内性能不佳。如果这个瓶颈在工作日结束时得到解决,那么这就解释了为什么下班后进度会加快这么多。