Condividi tramite


Non convergenza quando SQL Server elabora generazioni figlio e padre in batch di generazione separati

Questo articolo illustra come risolvere il problema di non convergenza che si verifica quando SQL Server elabora le generazioni figlio e padre in batch di generazione separati.

Versione originale del prodotto: SQL Server
Numero KB originale: 308266

Sintomi

Una perdita di comandi INSERT in tabelle figlio in un sottoscrittore può verificarsi nelle condizioni seguenti:

  • La topologia di replica di tipo merge è gerarchica, con un server di pubblicazione, uno o più ripubblicazioni e uno o più sottoscrittori.
  • Uno o più articoli padre e figlio esistono in una pubblicazione di replica di tipo merge, con un filtro join definito tra di essi.
  • Esiste un NOT FOR REPLICATION vincolo di chiave esterna nel server di ripubblicazione e nel sottoscrittore per la relazione tra questi due articoli.
  • Gli INSERT in un articolo figlio si verificano in una generazione separata dalla generazione padre associata da più del valore specificato nel parametro dell'agente -DownloadGenerationsPerBatch di merge. L'agente di merge elabora quindi la generazione figlio in un batch di generazioni separate dalla generazione padre associata.
  • Si verifica un'interruzione dell'elaborazione di merge tra il server di pubblicazione e la ripubblicazione e tra l'elaborazione dei batch di generazione figlio e padre.

Soluzione alternativa

L'architettura di replica di tipo merge non fornisce un meccanismo per mantenere insieme le modifiche padre e figlio attraverso i limiti del batch di generazione. Per risolvere questo problema, è possibile:

  • Aumentare i -UploadGenerationsPerBatch parametri e -DownloadGenerationsPerBatch agente di merge al valore massimo di 2000, eliminando virtualmente la possibilità di elaborare la generazione di un articolo figlio in un batch separato dalla generazione dell'articolo padre.

-OPPURE-

  • Rimuovere la NOT FOR REPLICATION proprietà sui vincoli di chiave esterna nel server di ripubblicazione. In questo caso, il agente di merge non è in grado di inserire righe nell'articolo figlio perché non sono presenti righe padre-articolo associate. Tenere presente, tuttavia, che potrebbe verificarsi una riduzione delle prestazioni associata a questa modifica. Se il agente di merge non è in grado di inserire queste righe figlio, è necessario ritentare tali modifiche. Il processo di ripetizione dei tentativi agente di merge è molto meno efficiente rispetto alla modalità normale di elaborazione batch.

Ulteriori informazioni

Ecco una sequenza più dettagliata di eventi in cui può verificarsi questo problema. I valori predefiniti per i -UploadGenerationsPerBatch parametri e -DownloadGenerationsPerBatch agente di merge (che presentano pesantemente questo problema) sono 100. Nell'esempio seguente si supponga che i -UploadGenerationsPerBatch parametri e -DownloadGenerationsPerBatch non siano stati modificati.

  • Gli INSERT si verificano nel server di pubblicazione di livello superiore in un elemento figlio e in un articolo padre. Un articolo figlio è qualsiasi articolo di una pubblicazione con un vincolo di chiave esterna a un'altra tabella, detto articolo padre. Questi due articoli sono correlati da un filtro join di replica di tipo merge e i vincoli di chiave esterna sul lato server effettivi nel republisher e nel sottoscrittore sono contrassegnati con la proprietà NOT FOR REPLICATION. È possibile eseguire la stored procedure sp_help nelle tabelle per determinare se i vincoli non sono disponibili per la replica, se non si è certi.
  • Gli INSERT nella tabella figlio si verificano (ad esempio) nella generazione 110. Gli INSERT nella tabella padre si verificano (ad esempio) nella generazione 250. La separazione tra queste generazioni è maggiore del -DownloadGenerationsPerBatch parametro .
  • Il server di pubblicazione-ripubblicazione agente di merge elabora il batch di generazioni che contengono generazioni da 101 a 200. Dopo l'elaborazione corretta di questo batch e un download delle modifiche associate in tali generazioni nel ripubblicatore, il server di pubblicazione-ripubblicazione agente di merge viene interrotto. L'interruzione si verifica prima che il agente di merge possa elaborare le generazioni da 201 a 300 (contenente le modifiche dell'articolo padre). L'interruzione può essere dovuta alla perdita di connettività di rete, a un timeout della query e così via. Il agente di merge può eseguire il commit delle righe dell'articolo figlio senza le righe padre perché il vincolo di chiave esterna lato server è contrassegnato come NOT FOR REPLICATION, in modo da "sospendere" il controllo del vincolo.
  • Prima che il server di pubblicazione-ripubblicazione agente di merge inizi di nuovo l'elaborazione, il sottoscrittore di ripubblicazione agente di merge avvia una sessione di merge. Inizia il processo di download delle modifiche dal server di ripubblicazione.
  • Quando il sottoscrittore di ripubblicazione agente di merge elabora la generazione 110 (l'articolo figlio INSERT), valuta il filtro join presente tra l'articolo figlio e l'articolo padre. Poiché le modifiche dell'articolo padre non sono ancora arrivate al ripubblicatore, il agente di merge determina che questi INSERT figlio non "qualificano" il filtro join. Il agente di merge scarica la riga MSmerge_genhistory che rappresenta la generazione 110, ma nessuna delle modifiche apportate alla generazione. Questa agente di merge completa correttamente la sessione.
  • Un'esecuzione successiva del agente di merge tra il server di pubblicazione e la ripubblicazione elabora correttamente il batch di generazioni che contengono gli INSERT dell'articolo padre (generazioni da 201 a 300) ed esegue il commit di tali modifiche nel server di ripubblicazione.
  • Infine, una sessione di agente di merge successiva tra il server di ripubblicazione e il sottoscrittore considera la generazione 250 e scarica gli INSERT dell'articolo padre nel sottoscrittore. Tuttavia, poiché il sottoscrittore conosce anche la generazione 110 (generazione dell'articolo figlio), il agente di merge non valuta nuovamente la partizione dell'articolo figlio.

Ciò comporta la presenza delle righe corrette dell'articolo padre nel sottoscrittore con orphaned righe figlio nel server di ripubblicazione.