Condividi tramite


Come la replica di tipo merge tiene traccia ed enumera le modifiche

Dopo l'inizializzazione di una pubblicazione o di una sottoscrizione, la replica di tipo merge tiene traccia ed enumera tutte le modifiche apportate ai dati nelle tabelle pubblicate. Le modifiche vengono rilevate tramite trigger (che vengono creati dalla replica per ogni tabella pubblicata) e tabelle di sistema nei database di pubblicazione e di sottoscrizione. Queste tabelle di sistema di replica vengono popolate con metadati che indicano quali modifiche devono essere propagate. Quando l'agente di merge viene eseguito durante la sincronizzazione, le modifiche vengono enumerate dall'agente e quindi applicate al Publisher e al Subscriber secondo le necessità.

Tracciamento delle modifiche

La replica di tipo merge usa i trigger e le tabelle di sistema seguenti per tenere traccia delle modifiche per tutte le tabelle pubblicate:

  • MSmerge_ins_<GUID>: trigger di inserimento (il valore GUID per questo trigger e gli altri trigger sono derivati da sysmergearticles)
  • MSmerge_upd_<GUID>: trigger di aggiornamento
  • MSmerge_del_<GUID>: trigger di eliminazione
  • MSmerge_contents
  • MSmerge_tombstone
  • MSmerge_genhistory

La replica di tipo merge usa le tabelle di sistema aggiuntive seguenti per tenere traccia delle modifiche per le tabelle filtrate:

  • MSmerge_partition_groups
  • MSmerge_current_partition_mappings
  • MSmerge_past_partition_mappings

Annotazioni

Le tabelle di sistema elencate vengono utilizzate da tutte le pubblicazioni e le sottoscrizioni di tipo merge in un database; Ad esempio, se si dispone di più pubblicazioni in un database di pubblicazione, MSmerge_contents contiene righe di articoli in tutte le pubblicazioni.

Rilevamento delle modifiche per le tabelle non filtrate

Tabelle di sistema

Le tabelle di sistema usate per tabelle non filtrate e filtrate contengono i metadati seguenti:

  • MSmerge_contents contiene una riga per ogni riga inserita o aggiornata in una tabella pubblicata nel database.

  • MSmerge_tombstone contiene una riga per ogni riga eliminata da una tabella pubblicata nel database.

  • MSmerge_genhistory contiene una riga per ogni generazione. Una generazione è una raccolta di modifiche recapitate a un server di pubblicazione o a un Sottoscrittore. Le generazioni vengono chiuse ogni volta che viene eseguito l'agente di merge; le successive modifiche in un database vengono aggiunte a una o più generazioni aperte.

Processo di rilevamento delle modifiche

Per tutte le tabelle non filtrate viene usato il processo di rilevamento delle modifiche seguente:

  • Quando si verifica un inserimento o un aggiornamento in una tabella pubblicata, si attiva il trigger MSmerge_ins_<GUID> o il trigger MSmerge_upd_<GUID> e una riga viene inserita nella tabella di sistema MSmerge_contents. La rowguid colonna di MSmerge_contents contiene il GUID per la riga inserita o aggiornata, indicando che alla successiva sincronizzazione, la riga inserita o aggiornata corrispondente nella tabella utente deve essere inviata al Publisher o ai sottoscrittori. Se si verificano aggiornamenti successivi in una riga di una tabella utente, la riga in MSmerge_contents viene aggiornata in modo da riflettere questo stato.

  • Quando si verifica un'eliminazione in una tabella pubblicata, il trigger MSmerge_del_<GUID> si attiva e viene inserita una riga nella tabella di sistema MSmerge_tombstone. La colonna rowguid di MSmerge_tombstone contiene il GUID per la riga eliminata, indicando che alla prossima sincronizzazione, è necessario inviare un'eliminazione all'Editore o ai Sottoscrittori per la riga corrispondente eliminata nella tabella degli utenti. Se viene fatto riferimento alla riga eliminata in MSmerge_contents (perché è stato inserito o aggiornato dall'ultima sincronizzazione), la riga viene eliminata da MSmerge_contents.

Rilevamento delle modifiche per le tabelle filtrate

Tabelle di sistema

Oltre alle tabelle di sistema descritte nella sezione precedente, tre tabelle nel database di pubblicazione contengono metadati per tenere traccia delle modifiche alle tabelle filtrate:

  • MSmerge_partition_groups contiene una riga per ogni partizione definita in una pubblicazione. Le partizioni possono essere:

    • Definito in modo esplicito utilizzando sp_addmergepartition o la pagina Partizioni dati della finestra di dialogo Proprietà pubblicazione.

    • Creato automaticamente quando un Sottoscrittore si sincronizza se il Sottoscrittore richiede una partizione che non dispone ancora di una registrazione in MSmerge_partition_groups.

  • MSmerge_current_partition_mappings contiene una riga per ogni combinazione univoca di righe in MSmerge_contents e MSmerge_partition_groups. Ad esempio, se una riga di una tabella utente appartiene a due partizioni e la riga viene aggiornata, viene inserita una riga in MSmerge_contents per riflettere l'aggiornamento e due righe vengono inserite in MSmerge_current_partition_mappings, per indicare che la riga aggiornata appartiene alle due partizioni.

  • MSmerge_past_partition_mappings contiene una riga per ogni riga che non appartiene più a una determinata partizione. Una riga si sposta all'esterno di una partizione se:

    • La riga viene eliminata. Se una riga viene eliminata da una tabella utente, viene inserita una riga in MSmerge_tombstone e una o più righe vengono inserite in MSmerge_past_partition_mappings.

    • Il valore in una colonna utilizzata per il filtro è stato modificato. Ad esempio, se un filtro con parametri si basa sullo stato in cui una società ha sede e la società si sposta, la riga per l'azienda (e le righe correlate in altre tabelle) potrebbe uscire dalla partizione di dati di un venditore nella partizione per un altro venditore. Se una riga viene aggiornata in modo che non appartenga più a una partizione, una riga viene inserita o aggiornata in MSmerge_contents e una o più righe vengono inserite in MSmerge_past_partition_mappings.

Annotazioni

Se vengono utilizzate partizioni non sovrapposte con una sottoscrizione per partizione (un valore di 3 per il parametro @partition_options di sp_addmergearticle), le tabelle di sistema MSmerge_current_partition_mappings e MSmerge_past_partition_mappings non vengono utilizzate per tenere traccia dei mapping delle partizioni delle righe, perché ogni riga appartiene a una sola partizione e può essere modificata solo su un sottoscrittore.

Processo di rilevamento delle modifiche

Il processo descritto in precedenza (nella sezione Rilevamento modifiche per le tabelle non filtrate) per le tabelle non filtrate viene usato anche per le tabelle filtrate, con le aggiunte seguenti:

  • Quando si verifica un inserimento in una tabella pubblicata, oltre ai dati da aggiornare o inserire in MSmerge_contents, viene aggiunto un mapping di partizione a MSmerge_current_partition_mappings per ogni partizione a cui appartiene la riga.

  • Quando si verifica un aggiornamento in una tabella pubblicata, oltre a dati aggiornati o inseriti in MSmerge_contents, se non esiste un mapping di partizione in MSmerge_current_partition_mappings per ogni partizione a cui appartiene la riga, ne viene aggiunto uno. Se l'aggiornamento ha generato lo spostamento di una riga da una partizione a un'altra, una riga viene aggiornata in MSmerge_current_partition_mappings e ne viene aggiunta una a MSmerge_past_partition_mappings.

  • Quando si verifica un'eliminazione in una tabella pubblicata, oltre a una riga inserita in MSmerge_tombstone, viene eliminata una riga da MSmerge_current_partition_mappings e ne viene aggiunta una a MSmerge_past_partition_mappings.

Modifica dell'enumerazione

Tabelle e procedure di sistema

Quando il Merge Agent viene eseguito, le modifiche vengono enumerate usando diverse tabelle di sistema e stored procedure.

  • MSmerge_genhistory contiene una riga per ogni generazione. Una generazione è una raccolta di modifiche recapitate a un server di pubblicazione o a un Sottoscrittore. Le generazioni vengono chiuse ogni volta che viene eseguito l'agente di merge; le successive modifiche in un database vengono aggiunte a una o più generazioni aperte.

  • sysmergesubscriptions contiene informazioni sulle sottoscrizioni, incluso un record delle ultime generazioni di modifiche inviate e ricevute da un nodo. Nel database di pubblicazione, questa tabella contiene una riga per il server di pubblicazione e una riga per ogni Sottoscrittore. In un database di sottoscrizione, questa tabella contiene in genere una riga per il Sottoscrittore e una riga per il server di pubblicazione.

  • MSmerge_generation_partition_mappings viene utilizzato solo per le tabelle filtrate, registrando se una determinata generazione contiene modifiche rilevanti per una determinata partizione. Questa tabella nel database di pubblicazione contiene una riga per ogni combinazione univoca di righe in MSmerge_genhistory e MSmerge_partition_groups.

  • sp_MSmakegeneration chiude tutte le generazioni aperte all'inizio del processo di enumerazione.

  • sp_MSenumchanges enumera le modifiche per le tabelle (in questo processo vengono usate anche diverse procedure correlate con nomi che iniziano con sp_MSenumchanges ).

  • sp_MSgetmetadata determina se una modifica da un nodo deve essere applicata a un altro nodo come inserimento, aggiornamento o eliminazione.

Processo di cambiamento dell'enumerazione

Durante l'enumerazione delle modifiche si verifica il processo seguente:

  1. La procedura sp_MSmakegeneration di sistema viene chiamata:

    • Per le tabelle non filtrate e filtrate, questa procedura chiude tutte le generazioni aperte a cui viene fatto riferimento in MSmerge_genhistory (le generazioni chiuse hanno un valore pari 1 o 2 nella colonna genstatus).

    • Per le tabelle filtrate, questa procedura popola la tabella MSmerge_generation_partition_mappingsdi sistema . Se una generazione contiene una o più modifiche rilevanti per una partizione, viene inserita una riga nella tabella di sistema. Se una generazione non contiene modifiche rilevanti per una determinata partizione, una riga non viene inserita in MSmerge_generation_partition_mappingse le modifiche non vengono enumerate per i Sottoscrittori che ricevono tale partizione.

  2. Vengono chiamate le stored procedure sp_MSenumchanges e le procedure correlate. Queste procedure enumerare le modifiche apportate dopo l'ultima sincronizzazione:

    1. Le procedure determinano innanzitutto la generazione in corrispondenza della quale viene avviata l'enumerazione, in base alle colonne sentgen (inviate dall'ultima generazione) e recgen (ultima generazione ricevuta) nella tabella sysmergesubscriptions.

      Ad esempio, quando si determinano le modifiche delle generazioni da enumerare per un determinato Sottoscrittore, vengono confrontati il sentgen del Sottoscrittore (archiviato nel database di pubblicazione) e il recgen del Sottoscrittore (archiviato nel database di sottoscrizione). Se i valori sono uguali (che indica che l'ultima generazione inviata dal server di pubblicazione è stata ricevuta correttamente dal Sottoscrittore), le modifiche vengono enumerate a partire dalla generazione successiva in MSmerge_genhistory. Se i valori non sono uguali, viene usato il valore inferiore dei due valori per assicurarsi che vengano inviate tutte le modifiche necessarie.

    2. Le procedure enumerano quindi le modifiche.

      Per le tabelle non filtrate, tutte le modifiche contenute nelle generazioni dopo la generazione in sentgen o recgen vengono enumerate: MSmerge_genhistory viene unito a MSmerge_contents e MSmerge_tombstone per determinare le modifiche da inviare.

      Per le tabelle filtrate, MSmerge_generation_partition_mappings viene unito a: MSmerge_current_partition_mappings e MSmerge_contentse MSmerge_past_partition_mappingsMSmerge_tombstone per determinare quali modifiche sono rilevanti per la partizione ricevuta dal Sottoscrittore.

  3. La stored procedure sp_MSgetmetadata viene chiamata per determinare se una modifica deve essere applicata come inserimento, aggiornamento o eliminazione. A questo punto, vengono eseguiti il rilevamento e la risoluzione dei conflitti; Per altre informazioni, vedere Come la replica di tipo merge rileva e risolve i conflitti.