Eu tenho um grupo de disponibilidade do SQL Server 2019 de dois nós com um banco de dados que possui CDC habilitado para várias tabelas. O CDC é usado para rastrear transações que não foram capturadas para população em um data warehouse.
O Grupo de Disponibilidade é configurado com failover de várias sub-redes, com secundários legíveis.
O aplicativo replica as transações capturadas via CDC usando sp_repltrans para obter uma lista de transações, que então lê por meio da função não documentada fn_dump_dblog
. Depois que uma transação for capturada e integrada ao data warehouse, o aplicativo marcará a transação como replicada por meio de sp_repldone . Nós o configuramos para ApplicationIntent=ReadOnly
conectar-se automaticamente ao nó secundário legível do Grupo de Disponibilidade.
O processo de captura/integração parece estar funcionando bem e se recupera bem durante um failover do Grupo de Disponibilidade, alternando automaticamente para o outro nó conforme necessário para manter uma conexão com um secundário legível. As transações estão sendo capturadas no data warehouse.
Depois que as transações são replicadas no data warehouse, o aplicativo é executado sp_repldone
no secundário, o que parece ter sido bem-sucedido, mas a transação nunca é marcada como replicada no primário, fazendo com que o log de transações seja relatado REPLICATION
na log_reuse_wait_desc
coluna de sys.databases
.
O aplicativo chama sp_repldone
assim:
EXEC sys.sp_repldone
@xactid = NULL
, @xact_seqno = NULL
, @numtrans= 0
, @time= 0
, @reset= 1;
O acima foi capturado por meio de Extended Events sp_statement_completed
. A sessão de captura de Eventos Estendidos também está configurada para capturar eventos de erro e nenhum está sendo relatado.
Se eu executar manualmente sp_repltrans
para obter uma lista de transações não replicadas e, em seguida, executar sp_repldone
essa lista no secundário, parece ter êxito sem problemas, mas o primário ainda acredita que as transações não foram replicadas. ou seja, a execução sp_repltrans
no primário ainda mostra transações aguardando replicação.
Não vejo nada nos documentos de sp_repldone indicando que ele pode ou não ser executado a partir de um secundário legível; na verdade, eu acho que retornaria um erro se não pudesse marcar as transações como replicadas, mas talvez haja um bug na implementação. É certo que esta configuração provavelmente não é tão comum. Se configurarmos o processo de captura/integração para anexar ao nó primário, removendo ApplicationIntent=ReadOnly
, a execução sp_repldone
no primário funcionará corretamente e todas as transações serão marcadas como replicadas, permitindo a reutilização do log de transações.
Há algo que precisa ser alterado para que isso funcione no secundário legível?
Relatei o comportamento por meio do site de Feedback do Azure aqui .
Como pano de fundo, presumo que esta seja uma solução CDC personalizada e que as tarefas regulares do CDC não estejam em execução para preencher as tabelas de alterações e executar sp_repldone e, portanto, você deve executar sp_repldone para permitir que o espaço do arquivo de log seja reutilizado após os backups de log. Para a maioria dos cenários, seria mais simples usar a Replicação Transacional para preencher o banco de dados de destino ou usar a solução CDC integrada e ler os dados alterados da réplica do banco de dados primário ou secundário.
sp_repldone "Atualiza o registro que identifica a última transação distribuída do servidor.", que fica armazenado no banco de dados. Portanto, definitivamente não pode funcionar em uma réplica somente leitura e provavelmente não está documentado o que faz quando você tenta.
E "Uma réplica secundária não pode atuar como editor ou republicador de replicação, mas a replicação deve ser configurada para que a secundária possa assumir o controle após um failover" Configurar a replicação com grupos de disponibilidade Always On
Portanto, este também não é um cenário compatível com replicação transacional integrada. E a incapacidade de marcar com êxito as transações como replicadas no segundo dia pode ser o motivo pelo qual não há suporte.
Pode funcionar bem ler as transações do secundário e conectar-se ao primário para executar sp_repldone, mas você precisará testar.