Come la replica di tipo merge rileva ed enumera le modifiche
In seguito all'inizializzazione di una pubblicazione o di una sottoscrizione, la replica di tipo merge rileva ed enumera tutte le modifiche apportate ai dati delle tabelle pubblicate. Tali modifiche vengono rilevate mediante trigger, che la replica crea per ogni tabella pubblicata, e tabelle di sistema nei database di pubblicazione e 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 server di pubblicazione e al Sottoscrittore nel modo appropriato.
Rilevamento delle modifiche
La replica di tipo merge utilizza i trigger e le tabelle di sistema che seguono per rilevare le modifiche relative a tutte le tabelle pubblicate:
MSmerge_ins_<GUID>: trigger di inserimento (il valore GUID per questo e gli altri trigger deriva 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 utilizza le seguenti tabelle di sistema aggiuntive per rilevare le modifiche per le tabelle filtrate:
MSmerge_partition_groups
MSmerge_current_partition_mappings
MSmerge_past_partition_mappings
Nota
Le tabelle di sistema elencate vengono utilizzate da tutte le sottoscrizioni e pubblicazioni di tipo merge in un database. Se, ad esempio, in un database di pubblicazione sono presenti più pubblicazioni, MSmerge_contents conterrà righe corrispondenti agli articoli di tutte le pubblicazioni.
Rilevamento delle modifiche per le tabelle non filtrate
Tabelle di sistema
Le tabelle di sistema utilizzate per le tabelle non filtrate e filtrate contengono i seguenti metadati:
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 e le modifiche successive in un database vengono aggiunte a una o più generazioni aperte.
Procedura di rilevamento delle modifiche
La seguente procedura di rilevamento delle modifiche viene utilizzata per tutte le tabelle non filtrate:
Quando viene eseguito un inserimento o un aggiornamento in una tabella pubblicata, viene attivato il trigger MSmerge_ins_<GUID> o MSmerge_upd_<GUID> e viene inserita una riga nella tabella di sistema MSmerge_contents. La colonna rowguid di MSmerge_contents contiene il GUID per la riga inserita o aggiornata, a indicare che alla successiva sincronizzazione è necessario inviare al server di pubblicazione o ai Sottoscrittori la riga inserita o aggiornata corrispondente nella tabella utente. In caso di aggiornamenti successivi in una riga di una tabella utente, la riga in MSmerge_contents viene aggiornata per rifletterli.
Quando viene eseguita un'eliminazione in una tabella pubblicata, viene attivato il trigger MSmerge_del_<GUID> e viene inserita una riga nella tabella di sistema MSmerge_tombstone. La colonna rowguid di MSmerge_tombstone contiene il GUID per la riga eliminata, a indicare che alla successiva sincronizzazione è necessario inviare un'eliminazione al server di pubblicazione o ai Sottoscrittori per la riga eliminata corrispondente nella tabella utente. Se nella tabella MSmerge_contents viene fatto riferimento alla riga eliminata, in quanto inserita o aggiornata in seguito all'ultima sincronizzazione, la riga viene eliminata dalla tabella.
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 il rilevamento delle modifiche apportate alle tabelle filtrate:
MSmerge_partition_groups contiene una riga per ogni partizione definita in una pubblicazione. Le partizioni possono essere:
Definite esplicitamente utilizzando sp_addmergepartition o la pagina Partizioni dati della finestra di dialogo Proprietà pubblicazione.
Create automaticamente quando un Sottoscrittore effettua la sincronizzazione, se quest'ultimo richiede una partizione che non include ancora una voce in MSmerge_partition_groups.
MSmerge_current_partition_mappings contiene una riga per ogni combinazione univoca di righe in MSmerge_contents e MSmerge_partition_groups. Se, ad esempio, 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 altre due righe vengono inserite in MSmerge_current_partition_mappings a 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 viene spostata 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 vengono inserite una o più righe in MSmerge_past_partition_mappings.
Il valore di una colonna utilizzata per il filtraggio è stato modificato. Se, ad esempio, un filtro con parametri si basa sullo stato in cui è presente la sede centrale di un'azienda e la società viene trasferita, è possibile che la riga relativa a tale società e quelle correlate presenti in altre tabelle vengano spostate all'esterno della partizione di dati di un venditore nella partizione di un altro venditore. Se una riga viene aggiornata in modo da non appartenere più a una partizione, viene inserita o aggiornata una riga in MSmerge_contents e vengono inserite una o più righe in MSmerge_past_partition_mappings.
Nota
Se vengono utilizzate partizioni non sovrapposte con una sottoscrizione per partizione (un valore pari a 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 rilevare i mapping di partizione, in quanto ogni riga appartiene a una sola partizione e può essere modificata in un unico Sottoscrittore.
Procedura di rilevamento delle modifiche
La procedura descritta nella sezione precedente "Rilevamento delle modifiche per le tabelle non filtrate" è valida anche per le tabelle filtrate, con le seguenti aggiunte:
Quando viene effettuato un inserimento in una tabella pubblicata, oltre ai dati aggiornati o inseriti in MSmerge_contents, viene aggiunto un mapping di partizione a MSmerge_current_partition_mappings per ogni partizione alla quale appartiene la riga.
Quando viene effettuato un aggiornamento in una tabella pubblicata, oltre ai dati aggiornati o inseriti in MSmerge_contents, se non è disponibile alcun mapping di partizione in MSmerge_current_partition_mappings per ogni partizione a cui appartiene la riga, ne viene aggiunto uno. Se l'aggiornamento ha causato lo spostamento di una riga da una partizione all'altra, viene aggiornata una riga 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 all'inserimento di una riga in MSmerge_tombstone, viene eliminata una riga da MSmerge_current_partition_mappings e ne viene aggiunta una a MSmerge_past_partition_mappings.
Enumerazione delle modifiche
Tabelle di sistema e procedure
Quando viene eseguito l'agente di merge, le modifiche vengono enumerate utilizzando un determinato numero di 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 e le modifiche successive 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 generalmente contiene una riga per il Sottoscrittore e una riga per il server di pubblicazione.
MSmerge_generation_partition_mappings viene utilizzata solo per le tabelle filtrate e indica se una determinata generazione contiene modifiche rilevanti per una specifica partizione. Questa tabella del 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 della procedura di enumerazione.
sp_MSenumchanges enumera le modifiche relative alle tabelle. Durante questa procedura vengono utilizzate anche alcune procedure correlate con nomi che iniziano con sp_MSenumchanges.
sp_MSgetmetadata determina se è necessario applicare una modifica di un nodo a un altro nodo come inserimento, aggiornamento o eliminazione.
Procedura di enumerazione delle modifiche
Durante l'enumerazione delle modifiche viene effettuata la seguente procedura:
Viene chiamata la procedura di sistema sp_MSmakegeneration:
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 il valore 1 o 2 nella colonna genstatus).
Per le tabelle filtrate, questa procedura popola la tabella di sistema MSmerge_generation_partition_mappings. 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, viene inserita una riga in MSmerge_generation_partition_mappings e le modifiche non vengono enumerate per i Sottoscrittori che ricevono tale partizione.
Vengono chiamate la stored procedure sp_MSenumchanges e le stored procedure correlate. Tali procedure enumerano le modifiche apportate dall'ultima sincronizzazione:
Le procedure determinano innanzitutto la generazione per l'inizio dell'enumerazione, in base alle colonne sentgen (ultima generazione inviata) e recgen (ultima generazione ricevuta) nella tabella sysmergesubscriptions.
Quando, ad esempio, si stabilisce quali modifiche delle generazioni devono essere enumerate per un determinato Sottoscrittore, le colonne del Sottoscrittore sentgen (archiviata nel database di pubblicazione) e recgen (archiviata nel database di sottoscrizione) vengono confrontate. Se i valori corrispondono, a indicare 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 invece i valori non coincidono, quello più basso viene utilizzato per garantire che tutte le modifiche richieste vengano inviate.
Le procedure enumerano quindi le modifiche:
Per le tabelle non filtrate, tutte le modifiche contenute nelle generazioni dopo la generazione della colonna sentgen o recgen vengono enumerate: MSmerge_genhistory viene unita in join a MSmerge_contents e MSmerge_tombstone per stabilire quali modifiche devono essere inviate.
Per le tabelle filtrate, MSmerge_generation_partition_mappings viene unita in join a: MSmerge_current_partition_mappings e MSmerge_contents, nonché MSmerge_past_partition_mappings e MSmerge_tombstone per stabilire quali modifiche sono rilevanti per la partizione ricevuta dal Sottoscrittore.
Per determinare se una modifica deve essere applicata come inserimento, aggiornamento o eliminazione, viene chiamata la stored procedure sp_MSgetmetadata. A questo punto, vengono eseguite le procedure di rilevamento e risoluzione dei conflitti. Per ulteriori informazioni, vedere Modalità di rilevamento e risoluzione dei conflitti da parte della replica di tipo merge.
Vedere anche