Um de nossos editores é assinado por três assinantes, cada assinante é hospedado em seu próprio servidor físico. Dois desses assinantes são 2008R2 e o terceiro 2012. O assinante 2012 está experimentando latência diariamente durante os horários de pico.
Depois de executar algum rastreamento de evento estendido por alguns dias, posso ver que a latência coincide com tempos de execução sp_MSget_repl_commands lentos no distribuidor e, mais especificamente, a consulta de seleção final encontrada na linha 724 "-- Mini join junto. Apenas agent_id e colunas article_id em dbo.MSsubscriptions". O tempo de execução dessa instrução pode chegar a >= 20 minutos.
O thread do leitor do distribuidor espera que toda a execução de sp_MSget_repl_commands seja concluída antes de começar a gravar comandos replicados nos buffers de comando? Ou ele começa a gravar comandos replicados nos buffers de comando assim que são retornados pelo SP? Vejo que a declaração problemática é sugerida com OPTION (FAST 1), o que pode sugerir que esse é o caso. Se o thread do leitor aguardar a conclusão de sp_MSget_repl_commands antes de começar a gravar comandos replicados no buffer de comando, isso pode explicar a latência, caso contrário, não tenho certeza. Há mais alguma coisa óbvia que eu possa monitorar?
O MSdistribution_history.comments sugere que o assalto está no assinante. No entanto, nenhum procedimento armazenado de assinante replicado está sendo concluído em >= 100 ms e não há nenhuma contenção de recursos do servidor físico óbvio. Descartei a rede porque também há outros bancos de dados de assinantes no mesmo servidor físico sendo preenchidos na mesma rede que não estão experimentando latência.
Para responder à minha própria pergunta até certo ponto. Os comandos parecem ser gravados no buffer de comando assim que sp_MSget_repl_commands os torna disponíveis. Se o thread do gravador não puder gravar o comando no assinante, sp_MSget_repl_commands girará até que o comando seja gravado. Depois de gravado, o gravador notifica o leitor e libera um dos dois buffers de comando para o próximo lote de comandos. Isso explica a longa execução de sp_MSget_repl_commands.