Condividi tramite


Peer-to-peer - Rilevamento dei conflitti nella replica peer-to-peer

Si applica a: SQL Server

La replica transazionale peer-to-peer consente di inserire, aggiornare o eliminare dati in qualsiasi nodo di una topologia e di propagare le modifiche agli altri nodi. Poiché è possibile modificare i dati in qualsiasi nodo, si potrebbe verificare un conflitto tra le modifiche apportate ai dati in nodi diversi. Se una riga viene modificata in più nodi, può causare un conflitto o persino la perdita di un aggiornamento quando viene propagata in altri nodi.

La replica peer-to-peer fornisce l'opzione che consente di abilitare il rilevamento dei conflitti in una topologia peer-to-peer. Questa opzione consente di prevenire i problemi causati da conflitti non rilevati, incluso il comportamento incoerente dell'applicazione e la perdita di aggiornamenti. Se questa opzione è abilitata, per impostazione predefinita una modifica in conflitto viene considerata come un errore critico che impedisce il corretto funzionamento dell'agente di distribuzione. In caso di conflitto, la topologia rimane in uno stato incoerente finché il conflitto non viene risolto e i dati non vengono resi coerenti nell'intera topologia.

Nota

Per prevenire potenziali incoerenze dei dati, evitare che si verifichino conflitti in una topologia peer-to-peer, anche quando il rilevamento dei conflitti è abilitato. Per garantire che le operazioni di scrittura relative a una determinata riga vengano eseguite in un unico nodo, le applicazioni che accedono e modificano i dati devono partizionare le operazioni di inserimento, aggiornamento ed eliminazione. Tale partizionamento assicura che le modifiche apportate a una determinata riga in un singolo nodo vengano sincronizzate con tutti gli altri nodi della topologia prima che la riga venga modificata da un nodo diverso. Se un'applicazione richiede funzionalità avanzate di rilevamento e risoluzione dei conflitti, utilizzare la replica di tipo merge. Per altre informazioni, vedere Replica di tipo merge e Rilevare e risolvere i conflitti tra repliche di tipo merge.

Informazioni sui conflitti e sul relativo rilevamento

In un singolo database le modifiche apportate alla stessa riga da applicazioni diverse non generano un conflitto, in quanto le transazioni sono serializzate e i blocchi gestiscono le modifiche simultanee. In un sistema distribuito asincrono, ad esempio la replica peer-to-peer, le transazioni agiscono in modo indipendente su ogni nodo e non sono presenti meccanismi per serializzarle tra più nodi. È possibile utilizzare un protocollo come il commit 2PC, che tuttavia influisce in modo significativo sulle prestazioni.

Nei sistemi come la replica peer-to-peer i conflitti non vengono rilevati quando viene eseguito il commit delle modifiche nei singoli peer. Vengono invece rilevati quando queste modifiche vengono replicate e applicate in altri peer. Nella replica peer-to-peer i conflitti vengono rilevati dalle stored procedure che applicano le modifiche a ogni nodo, in base a una o più colonne nascoste in ogni tabella pubblicata.

Prima di SQL Server 2019 (15.x) CU 13, SQL Server aggiunge una colonna nascosta a ogni tabella pubblicata: $sys_p2p_cd_id. Questa colonna nascosta archivia un ID costituito dalla combinazione tra un ID origine specificato per ogni nodo e la versione della riga.

In SQL Server 2019 (15.x) CU 13 e versioni successive, se crei la pubblicazione peer-to-peer con @p2p_conflictdetection_policy = 'lastwriter', poi SQL Server aggiunge una colonna nascosta aggiuntiva a ogni tabella pubblicata: $sys_md_cd_id. Questa colonna nascosta memorizza il datetime come tipo di dati datetime2.

Durante la sincronizzazione, l'agente di distribuzione esegue le procedure per ogni tabella. Queste procedure applicano le operazioni di inserimento, aggiornamento ed eliminazione da altri peer. Se una delle procedure rileva un conflitto quando legge il valore o i valori della colonna nascosta, genera l'errore 22815 con un livello di gravità 16:

A conflict of type '%s' was detected at peer %d between peer %d (incoming), transaction id %s and peer %d (on disk), transaction id %s

Per impostazione predefinita, a causa di questo errore l'agente di distribuzione arresta l'applicazione di modifiche a tale nodo. Per informazioni su come gestire i conflitti rilevati, vedi Gestione dei conflitti.

Nota

Alla colonna nascosta può accedere solo un utente connesso tramite la connessione amministrativa dedicata (DAC, Dedicated Administrator Connection). Per informazioni sulle connessioni DAC, vedere Connessione di diagnostica per gli amministratori di database.

La replica peer-to-peer rileva i tipi seguenti di conflitti:

  • Inserimento-inserimento

    Tutte le righe di ogni tabella che partecipa alla replica peer-to-peer sono identificate in modo univoco tramite valori di chiave primaria. Un conflitto di tipo inserimento-inserimento si verifica quando viene inserita una riga con lo stesso valore di chiave in più di un nodo.

  • Aggiornamento-aggiornamento

    Si verifica quando la stessa riga viene aggiornata in più di un nodo.

  • Inserimento-aggiornamento

    Si verifica se una riga viene aggiornata in un nodo ma viene anche eliminata e quindi reinserita in un altro nodo.

  • Inserimento-eliminazione

    Si verifica se una riga viene eliminata in un nodo ma viene anche eliminata e quindi reinserita in un altro nodo.

  • Aggiornamento-eliminazione

    Si verifica se una riga viene aggiornata in un nodo ma viene anche eliminata in un altro nodo.

  • Eliminazione-eliminazione

    Si verifica quando una riga viene eliminata in più di un nodo.

Abilitazione del rilevamento dei conflitti

Per usare il rilevamento dei conflitti, abilita il rilevamento per tutti i nodi. Per impostazione predefinita, il rilevamento dei conflitti è abilitato quando configuri la replica peer-to-peer in SQL Server Management Studio. Si consiglia di lasciare abilitato il rilevamento, anche negli scenari in cui non si prevedono conflitti. Per abilitare e disabilitare il rilevamento dei conflitti, è possibile utilizzare le stored procedure di Management Studio o Transact-SQL:

  • Per abilitare e disabilitare il rilevamento in Management Studio, è possibile utilizzare la pagina Opzioni della sottoscrizione della finestra di dialogo Proprietà pubblicazione o la pagina Configura topologia della Configurazione guidata topologia peer-to-peer.

    Se configuri il rilevamento dei conflitti utilizzando Management Studio, l'agente di distribuzione viene configurato per arrestare l'applicazione di modifiche quando viene rilevato un conflitto.

  • Per abilitare e disabilitare il rilevamento, è anche possibile utilizzare le stored procedure seguenti:

    • sp_addpublication

    • sp_configure_peerconflictdetection.

      Se si configura il rilevamento dei conflitti utilizzando le stored procedure, è possibile specificare se l'agente di distribuzione deve arrestare l'applicazione di modifiche quando viene rilevato un conflitto. Per impostazione predefinita, l'agente si arresta. È consigliabile utilizzare l'impostazione predefinita.

Gestione dei conflitti

Quando si verifica un conflitto nella replica peer-to-peer, viene generato l'avviso di rilevamento dei conflitti peer-to-peer. Configura questo avviso in modo da ricevere una notifica quando si verifica un conflitto. Per altre informazioni sugli avvisi, vedere Usare gli avvisi per gli eventi degli agenti di replica.

Dopo l'arresto dell'agente di distribuzione e la generazione dell'avviso, utilizzare uno degli approcci seguenti per gestire i conflitti che si sono verificati:

  • Reinizializzare il nodo in cui è stato rilevato il conflitto dal backup di un nodo contenente i dati necessari (approccio consigliato). Questo metodo assicura che i dati siano in uno stato coerente.

  • Tentare di sincronizzare nuovamente il nodo consentendo all'agente di distribuzione di continuare ad applicare le modifiche:

    1. Eseguire sp_changepublication: specificare 'p2p_continue_onconflict' per il parametro @property e true per il parametro @value.

    2. Riavviare l'agente di distribuzione.

    3. Verificare i conflitti rilevati utilizzando il Visualizzatore conflitti e determinare le righe coinvolte, il tipo di conflitto e la riga in conflitto confermata. Il conflitto viene risolto in base al valore di ID origine specificato durante la configurazione: la riga che ha origine nel nodo con l'ID più alto è la riga in conflitto confermata. Per altre informazioni, vedi Visualizzare i conflitti di dati per le pubblicazioni transazionali (SQL Server Management Studio).

    4. Eseguire la convalida per assicurare la corretta convergenza delle righe in conflitto. Per altre informazioni, vedere Convalidare i dati replicati.

      Nota

      Se i dati sono incoerenti dopo questo passaggio, è necessario aggiornare manualmente le righe sul nodo con la massima priorità, quindi consentire la propagazione delle modifiche da questo nodo. Se non sono presenti ulteriori modifiche in conflitto nella topologia, tutti i nodi verranno portati in uno stato coerente.

    5. Eseguire sp_changepublication: specificare 'p2p_continue_onconflict' per il parametro @property e false per il parametro @value.

Gestire automaticamente i conflitti con la priorità dell'ultima scrittura.

A partire da SQL Server 2019 (15.x) CU 13, puoi configurare la replica peer-to-peer per risolvere automaticamente i conflitti consentendo l'inserimento o l'aggiornamento più recente per risolvere il conflitto. Se una delle due operazioni di scrittura elimina la riga, SQL Server consente all'eliminazione di vincere il conflitto. Questo metodo è noto come priorità dell’ultima scrittura.

Usa le stored procedure per configurare le priorità dell'ultima scrittura. Vedi Configurare il rilevamento e la risoluzione dei conflitti dell'ultima scrittura. Non è possibile configurare le priorità dell'ultima scrittura con SQL Server Management Studio.

Nota

La replica peer-to-peer con la priorità dell'ultima scrittura dipende dalla presenza degli orologi dei nodi partecipanti nella sincronizzazione per ottenere risultati affidabili. Se gli orologi dei server partecipanti diventano troppo non sincronizzati, il risultato di una risoluzione dei conflitti potrebbe essere imprevisto e/o indesiderato. Ad esempio, se il server A ha un orologio preciso, ma il server B è una settimana indietro, il server A verrà scelto per vincere ogni conflitto, anche se oggettivamente non è stato l’ultimo ad aggiornare la riga. Se non è possibile mantenere gli orologi entro la tolleranza necessaria per la risoluzione dei risultati, puoi scegliere una strategia di risoluzione dei conflitti diversa.