Estou com um problema estranho aqui. Eu estava testando o uso de 'initialize from lsn' em nossa configuração de replicação de teste e agora quebrei todas as publicações de um de nossos bancos de dados, a reconstrução do zero (aplicando um novo instantâneo) não corrigiu o problema.
No monitor de replicação, o agente distribuidor é executado continuamente e relata:
Nenhuma transação replicada está disponível
O token Tracer está relatando que:
- Editor para Distribuidor: 00:00:02
- Distribuidor para Assinante: Pendente...
- Latência total: pendente...
Quando investiguei os logs de distribuição usando:
SELECT time,
CAST(comments AS XML) AS comments,
runstatus,
duration,
xact_seqno,
delivered_transactions,
delivered_commands,
average_commands,
delivery_time,
delivery_rate,
delivery_latency / (1000 * 60) AS delivery_latency_Min,
agent_id
FROM dbo.MSlogreader_history WITH (NOLOCK)
WHERE agent_id = 5
ORDER BY time DESC;
SELECT *
FROM dbo.MSdistribution_history
WHERE agent_id = 125
ORDER BY time DESC;
Eu posso ver que o último xact_seqno de:
- O agente LogReader é: 0x00000378000384880003
- O agente de distribuição é: 0x000CA68B000010A8000A000000070000
Como comparação em um dos outros bancos de dados (indo para o mesmo assinante), recebo:
- O agente LogReader é: 0x00000D140001F52A0003
- O agente de distribuição é: 0x00000D140001F52A0003000000000000
Para mim, parece que o agente de distribuição está lembrando do antigo xact_seqno quebrado (de quando cometi um erro ao testar 'initialize from lsn'), mas agora parece ter quebrado permanentemente toda a replicação desse banco de dados.
Servidores:
- PubA - Um editor hospeda vários bancos de dados que são replicados
- Dist - Um distribuidor separado
- SubA - Primeiro assinante
- SubB - Segundo assinante
Bancos de dados:
- PubA.DB1 = Publisher DB que está funcionando bem
- PubA.DB2 = DB Publisher que está quebrado
- SubA.PullWorking1 = 1º assinante tem uma assinatura pull em funcionamento do DB1
- SubA.PullBroken2 = 1º assinante também tem uma assinatura pull quebrada do DB2
- SubA.PushWorking1 = 2º assinante tem uma assinatura push funcional do DB1
- SubA.PushBroken2 = 2º assinante também tem uma assinatura push quebrada do DB2
Publicações:
- PubA.DB1.PushPub_works
- PubA.DB1.PullPub1_works
- PubA.DB1.PullPub2_works
- PubA.DB2.PushPub_broken
- PubA.DB2.PullPub_broken
Ok, caso alguém tenha esse problema, encontrei a correção (embora não a causa raiz).
Fixar
SELECT publication, '0x' + CONVERT(VARCHAR(32),MAX(transaction_timestamp),2) as LastPubLSN FROM dbo.MSreplication_subscriptions GROUP BY publication
DECLARE @Publisher sysname = N'PubA', @PubDB sysname = N'DB2', @Publication sysname = N'PushPub_Broken'; SELECT TOP 1000 trans.entry_time, trans.publisher_database_id, trans.xact_seqno FROM dbo.MSpublications AS p JOIN master..sysservers AS srv ON srv.srvid = p.publisher_id JOIN dbo.MSpublisher_databases AS d ON d.publisher_id = p.publisher_id AND d.publisher_db = p.publisher_db JOIN dbo.MSrepl_transactions AS trans ON trans.publisher_database_id = d.id WHERE p.publication = @Publication AND p.publisher_db = @PubDB AND srv.srvname = @Publisher AND trans.xact_seqno >= p.min_autonosync_lsn ORDER BY trans.entry_time DESC
DECLARE @PubDB INT = 5 /* use the publisher_database_id retrieved above */ select * from MSrepl_commands with (READPAST) where publisher_database_id = @PubDB and command_id = 1 and type <> 30 and /* 30 = normal repl commands */ type <> -2147483611 /* -2147483611 = is ignored by sp_MSget_repl_commands (it's snapshot related?) */
EXEC sp_setsubscriptionxactseqno @publisher = 'PubA', @publisher_db = 'DB2', @publication = 'PushPub_Broken', @xact_seqno = 0x0000... /* New valid LSN to start from (step 3) */
Como eu encontrei
Então, depois de encontrar e testar sp_setsubscriptionxactseqno em conjunto com saber como obter o LastLSN aplicado ao assinante, executei um rastreamento no distribuidor, pude ver que a sequência era:
Executando o primeiro comando sozinho, pude ver 2 conjuntos de resultados retornados, o segundo dos quais incluía o LSN ruim. Obviamente, algo dentro deste proc estava fazendo com que ele substituísse o LSN que eu queria que ele aplicasse.
Encontrando o código para
sp_MSget_repl_commands
, consegui identificar que era:A partir daí, encontrei os registros culpados e consegui reiniciar a replicação (depois de ressincronizar meus dados)