Sincronizzazione di due database in SQL Server


16

Ho due database di SQL Server. Uno è client (applicazione Windows) e il secondo è sul server. Voglio sincronizzare questi due database ogni tanto (ad es. Ogni 2 minuti!).

Ho letto su diversi modi di sincronizzazione come replica, timestamp, tabelle di log utilizzando trigger, Microsoft Sync Framework e così via.

In realtà non mi piace usare un metodo di sincronizzazione che potrebbe essere una scatola nera (come la replica) perché non voglio che le tabelle specifiche di SQL Server vengano bloccate mentre le sto aggiornando e sincronizzandole con il server.

  1. quale metodo pensi che dovrei usare in tale circostanza? Ricorda che ogni pochi minuti devo inviare diverse modifiche alla tabella dal client al server e recuperare anche due modifiche alla tabella dal server.

  2. Ho trovato un metodo strano ma nuovo. È possibile che io registri tutte le procedure memorizzate eseguite (per specifiche preferite) nel client e le invii con i loro parametri in un .sqlfile al server e le esegua lì? Lo stesso accadrà sul server e verrà inviato al client. Pensi che questo sia un metodo semplice ma utile o no?

  3. per favore, suggeriscimi un approccio utile se puoi. Grazie mille.

EDIT: Ricorda che questa è una sincronizzazione in tempo reale e questo lo rende speciale. Significa che quando l'utente client utilizza la tabella, il processo di sincronizzazione con il server deve avvenire ogni pochi minuti, quindi nessuna delle tabelle deve essere bloccata.


1
Ricorda che quelle "scatole nere" sono relativamente ben documentate per quanto riguarda il loro funzionamento, come mantenerle e monitorarle e cosa puoi fare per risolverle in scenari di errore comuni (e non così comuni). Vorrei prendere in considerazione il rotolamento del mio metodo di sincronizzazione e la necessità di trovare e correggere bug relativi ai casi limite che le "scatole nere" hanno affrontato molto tempo fa se e solo se avessi esigenze specifiche dell'applicazione (sincronizzazione parziale o necessità di utente) risoluzione interattiva dei conflitti e così via).
David Spillett,

@DavidSpillett: hai utilizzato correttamente la replica in un progetto di sincronizzazione in tempo reale? La mia preoccupazione principale è la sincronizzazione in tempo reale e il "blocco e blocco".
Emad Farrokhi,

Risposte:


14

Beh, potrei non capirlo, ma provo a rispondere.

Hai detto che hai bisogno di una soluzione ad alte prestazioni che gira spesso (minimo tutti i 2 minuti) e hai bisogno di un buon approccio che dovrebbe essere veloce senza blocco. Ma non vuoi un sistema blackbox.

Invece di un sistema blackbox, che viene utilizzato su milioni di installazioni con buoni risultati, cerchi di inventare di nuovo la ruota e creare la tua soluzione? Hm, sembra un po 'strano.

In realtà questi sono i miei suggerimenti.

  1. replicazione anche se hai detto che non la userai. È la soluzione più semplice e migliore che puoi usare per questo. La replica è facile da configurare, replicare velocemente e non è necessario inventare di nuovo la ruota. Se sei solo strano sul blocco, puoi provare a impostare ISOLATION LEVELsu READ_COMMITTED_SNAPSHOT. Puoi leggere di più qui . Questo utilizzerà una parte del tuo tempdb, ma la tua tabella è sempre leggibile e scrivibile e la replica può funzionare in background.

Vedi l'esempio seguente:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. CDC (Change Data Capture) può anche essere una soluzione. Ma in questo modo devi costruire quasi tutto da solo. E ho fatto l'esperienza che CDCpuò essere una cosa fragile in alcune circostanze. CDCacquisirà tutti i dati su una tabella controllata (è necessario specificare manualmente ciascuna tabella controllata). Successivamente otterrai il valore prima e il valore dopo un INSERT, UPDATEo DELETE. CDCtratterrà tali informazioni per un periodo di tempo (è possibile specificarle da sole). L'approccio potrebbe essere quello di utilizzareCDC su alcune tabelle necessarie per guardare e replicare manualmente tali modifiche nell'altro database. A proposito, CDCusa anche la replica di SQL Server sotto il cofano. ;-) Puoi leggere di più qui .

Attenzione: CDCnon sarà a conoscenza di DDL-changes. Ciò significa che, se si modifica una tabella e si aggiunge una nuova colonna, CDCla tabella verrà controllata ma si ignoreranno tutte le modifiche alla nuova colonna. In effetti registra solo NULLcome valore prima e valore dopo. È necessario reinizializzarlo dopo DDL-Cambia a una tabella controllata.

  1. Il modo sopra descritto è come catturare un carico di lavoro usando SQL Server Profiler ed eseguirlo di nuovo su un altro database per alcuni benchmark. Beh, potrebbe funzionare. Ma il fatto che ci siano troppi effetti collaterali è un po 'troppo pesante per me. Cosa fare se si acquisisce una chiamata di procedura sul proprio client. Dopo aver eseguito lo stesso comando nel database principale perché non è sincronizzato? La procedura può essere eseguita, ma può eliminare / aggiornare / inserire righe che non erano presenti nel client. O come gestisci più clienti con un principio. Penso che sia troppo complicato. Nel peggiore dei casi, probabilmente distruggi la tua integrità.
  2. Un'altra idea potrebbe essere basata sull'applicazione o utilizzando un trigger. A seconda di quante tabelle si desidera sincronizzare. È possibile scrivere tutte le modifiche in una tabella di gestione temporanea separata ed eseguire un processo agente SQL Server tutti i x minuti per sincronizzare quelle righe nella tabella di gestione temporanea con il proprio master. Ma questo potrebbe essere un po 'troppo pesante se provi a sincronizzare (ad esempio) 150 tabelle. Avresti un grande sovraccarico.

Bene, questi sono i miei 2 centesimi. Spero che tu abbia una buona visione d'insieme e forse hai trovato una soluzione che funziona per te.


9

Cercherò di elencare alcune opzioni qui con vantaggi e svantaggi mentre le percepisco:

  1. Replica di SQL Server : si tratta dello strumento SQL Server nativo migliore e più ottimizzato per questa attività. Ma ci sono diversi problemi: a. per tutti i client, indipendentemente dal fatto che siano o meno database SQL Express, è necessaria la licenza CAL di SQL Server. Questo può essere evitato usando le licenze per processore. b. Non è possibile sincronizzare il client SQL CE come qui . c. SQL Express o LocalDB non possono fungere da editori o distributori , quindi hai meno controllo sul client sul processo di replica.
  2. Microsoft Sync Framework : mi sembra più adatto a database più piccoli di app mobili. Aggiunge molte tabelle al database e non è efficiente come la replica. Poiché è implementato all'esterno di SQL Server come componente, sarà più difficile da configurare. Non ho esperienza con esso, l'ho solo provato e ho deciso di non usarlo.

  3. Tracciamento delle modifiche al database . È una funzione integrata di SQL Server che fa per te il rilevamento delle modifiche, inclusi inserimenti, aggiornamenti ed eliminazioni. Tutto il resto, come l'invio e l'applicazione di modifiche, la risoluzione di conflitti ecc., Dovrai codificarti.

  4. Colonne Rowversion (timestamp) Se non si accettano tutte le eliminazioni (nessuna sincronizzazione dei record eliminati), è possibile implementare la propria soluzione basata solo sulle informazioni di Rowversion. Le colonne Rowversion vengono utilizzate anche dalla replica di SQL Server, quindi sarà necessario aggiungerle comunque.
  5. CDC come menzionato nella risposta di Ionic - Non ho esperienza con esso, poiché è disponibile solo nelle edizioni Enterprise o Developer.

  6. L'uso del proprio trucco con la registrazione di stored procedure eseguite dipende molto dalla natura dell'applicazione di database. Ma quando le procedure diventano leggermente diverse, è possibile ottenere un gran casino nei dati. E come gestiresti i conflitti?

Dalla tua domanda sembra che tu debba sincronizzare solo poche tabelle e non tutti i grandi database. A tale scopo, è necessario analizzare le esigenze in modo più dettagliato di quanto specificato nella domanda, ad esempio:

  • Le cancellazioni possono avvenire e cosa succede allora?
  • Possono verificarsi conflitti, come prevenirli e come risolverli?
  • Come gestirò le modifiche alla struttura della tabella?
  • ...

Se alla fine scopri che le cancellazioni e i conflitti non sono il tuo problema e che la tua struttura non cambierà molto, puoi considerare di scrivere la tua logica, ma può facilmente crescere fino a 1000 righe di codice.


2

Grazie a tutti voi per il feedback.

Ho risolto con successo il processo di sincronizzazione tramite l'acquisizione delle procedure memorizzate eseguite non come un gruppo ma uno per uno che ha funzionato alla grande nel mio caso. Poiché l'integrità e tutto è stato attentamente considerato, il sistema ha funzionato fino ad ora in tempo reale.


Fantastico, tuttavia, puoi spiegare più in dettaglio cosa hai fatto. Registri semplicemente le chiamate delle procedure memorizzate che sono state eseguite e le memorizzi in qualche tabella / script temporaneo e hai un lavoro che esegue questo script e che imposta un campo (come un campo bit o un campo datetime dove dici per TUTTI questi record che non sono stati elaborati li elaborano e aggiornano il campo bit?) Sono contento di aver risolto il problema, ma è necessario fornire maggiori informazioni su ciò che hai fatto per aiutare gli altri a imparare?
JonH,

0

Risposta in ritardo, ma potrebbe essere utile far passare i visitatori

Ho avuto una sfida simile cercando di distribuire i dati su server diversi e risolto utilizzando strumenti di terze parti ( Diff per le modifiche dello schema e DataDiff per la sincronizzazione delle modifiche dei dati) e seguendo lo script di PowerShell necessario per automatizzare il processo:

#check for the existence of the Outputs folder
function CheckAndCreateFolder($rootFolder, [switch]$Outputs)
{
$location = $rootFolder

#setting up location 
if($Outputs -eq $true)
{
    $location += "\Outputs"
}

#if the folder doesn't exist it will be created
if(-not (Test-Path $location))
{ mkdir $location -Force:$true -Confirm:$false | Out-Null }

return $location
}

#root folder for the schema sync process
$rootFolder = "SchemaSync"

#schema output summaries location 
$outsLoc = CheckAndCreateFolder $rootFolder -Outputs

#ApexSQL Diff location, date stamp variable is defined, along with tools parameters 
$diffLoc   = "ApexSQLDiff"
$stamp = (Get-Date -Format "MMddyyyy_HHMMss") 
$Params = "/pr:""MyProject.axds""    /out:""$outsLoc\SchemaOutput_$stamp.txt"" /sync /v /f" 
$returnCode = $LASTEXITCODE

#initiate the schema comparison and synchronization process
(Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params))

#write output to file
"$outsLoc\SchemaOutput_$dateStamp.txt"

#schema changes are detected
if($returnCode -eq 0)
{
"`r`n $returnCode - Schema changes were successfully synchronized" >> 

}
else
{
#there are no schema changes
if($returnCode -eq 102)
{
"`r`n $returnCode - There are no schema changes. Job aborted" >> 
}
#an error is encountered
else
{
"`r`n $returnCode - An error is encountered" >> 

#output file is opened when an error is encountered
Invoke-Item "$outsLoc\SchemaOutput_$stamp.txt"
}

}

Questo metodo pianifica il confronto tra due database e sincronizza le modifiche rilevate in tempo reale. Ecco alcuni articoli che offrono istruzioni dettagliate:

https://solutioncenter.apexsql.com/automatically-compare-and-synchronize-sql-server-data/ https://solutioncenter.apexsql.com/how-to-automatically-keep-two-sql-server-database- schemi-in-sync /

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.