辅助服务器上的只读查询不会返回正确的值

Set*_*ake 7 sql-server availability-groups sql-server-2019

我有两台服务器 A 和 B。两者都位于 Always On 组中。B 服务器配置为只读请求。到目前为止,这工作得很好,但最近查询服务时出现了问题。

该服务首先对表(可能在 A 服务器上)进行更新,然后在 B 服务器上进行只读选择。开发商表示,这是两笔独立的交易。

不幸的是,选择不会返回之前进行更新的值。仅在大约 1 到 1.5 秒后才会出现正确的值。我们以前从未能够观察到这种行为。

服务器设置为同步提交。所有数据库都是同步的,没有数据丢失。只读路由已经过测试并且有效。可读辅助设置为“是”。

我作为MSSQL数据库的DBA工作了大约1.5年,我不太明白AG中的两个节点A和B如何通信,但我假设两个节点会同时接收数据使用“同步提交”,对吗?

造成 1 到 1.5 秒时间差的原因是什么?

服务器是带有 CU12 的 SQL 2019 Enterprise - 在带有 Windows Server 2016 Standard 的一些功能强大的物理机上运行。

Sea*_*ser 12

该服务首先对表(可能在 A 服务器上)进行更新,然后在 B 服务器上进行只读选择。不幸的是,选择不会返回之前进行更新的值。仅在大约 1 到 1.5 秒后才会出现正确的值。

这是预期的,也是产品的设计方式。提交强化(同步提交)不包括重做,它仅包含辅助节点上的强化。Harden 和 Redo 是 SQL Server 中 AG 的两个截然不同的进程。

我不太明白AG中两个节点A和B是如何通信的,但我假设使用“同步提交”时两个节点会同时接收数据,对吧?

主要负责捕获打包到日志记录中的“更改”,这些更改又打包到日志块中。日志块(此处过于简化)在提交时关闭并刷新,然后用于相互独立地复制并发送到其他副本。根据各种因素,这可能是也可能不是一个快速的过程,因为它必须遍历其他层和线程。

最终,日志块将使其位于辅助服务器一侧,进行强化,并且根据合作伙伴类型,将立即发送进度消息或等待。当主节点收到发送该消息的特定副本的进度消息时,会更新各种内部值,并发生其他各种检查。无论合作伙伴类型如何(同步/异步),每个副本都会发生这种情况。

因此,不会在所有副本上同时接收数据,也不能保证在主副本上处理进度消息之前完成重做。

SQL Server 根据基于快照隔离的读取事务开始返回有效且正确的数据,而不是所需/预期的数据。


Zik*_*ato 8

同步无数据丢失仅意味着事务日志已在辅助副本上得到强化。它对重做阶段没有任何保证。

希望这张图片能解释这一点

同步提交模式图

图片来源:SQL AG数据同步延迟的常见原因及排查方案

辅助服务器上的日志重做可能会因多种原因而延迟,最常见的是它被阻止。您可以在默认扩展事件AlwaysOn_health事件lock_redo_blocked中检查重做块。

在此输入图像描述

我建议启用事件字段Resource_description(默认情况下不启用)。