我们的一个发布者由三个订阅者订阅,每个订阅者都托管在自己的物理服务器上。其中两个订阅者是 2008R2 和第三个 2012。2012 年订阅者在高峰时段每天都会遇到延迟。
在运行了几天的一些扩展事件跟踪之后,我可以看到延迟与分发器处的 sp_MSget_repl_commands 执行时间缓慢有关,更具体地说,在第 724 行找到的最终选择查询“--Mini join together。只有 agent_id 和dbo.MSsubscriptions 中的 article_id 列”。此语句的执行时间可能 >= 20 分钟。
在开始将复制的命令写入命令缓冲区之前,分发器读取器线程是否等待 sp_MSget_repl_commands 的整个执行完成?或者它是否在 SP 返回后立即将复制的命令写入命令缓冲区?我看到有问题的陈述是用 OPTION (FAST 1) 暗示的,这可能表明情况就是这样。如果读取器线程在开始将复制的命令写入命令缓冲区之前确实等待 sp_MSget_repl_commands 完成,那么这可能会解释延迟,否则我不确定。还有什么明显的我可以监控的吗?
MSdistribution_history.comments 表明劫持发生在订阅者处。但是,没有复制的订阅者存储过程在 >= 100 毫秒内完成,并且没有明显的物理服务器资源争用。我已经排除了网络,因为在同一物理服务器上还有其他订阅者数据库通过同一网络填充,这些数据库没有遇到延迟。
在一定程度上回答我自己的问题。一旦 sp_MSget_repl_commands 使命令可用,命令似乎就被写入命令缓冲区。如果编写器线程无法将命令写入订户,则 sp_MSget_repl_commands 将旋转直到命令被写入。一旦写入,写入器就会通知读取器并为下一批命令释放两个命令缓冲区中的一个。这解释了 sp_MSget_repl_commands 的长时间执行。