Synchronisieren von zwei Datenbanken in SQL Server

16

Ich habe zwei SQL Server-Datenbanken. Einer ist Client (Windows-Anwendung) und der zweite ist auf dem Server. Ich möchte diese beiden Datenbanken immer wieder synchronisieren (zB alle 2 Minuten!).

Ich habe Informationen zu verschiedenen Synchronisierungsmethoden wie Replikation, Zeitstempel, Protokolltabellen mithilfe von Triggern, Microsoft Sync Framework usw. erhalten.

Eigentlich möchte ich keine Synchronisationsmethode verwenden, die eine Blackbox sein könnte (wie die Replikation), weil ich nicht möchte, dass die SQL Server-spezifischen Tabellen blockiert werden, während ich sie aktualisiere und mit dem Server synchronisiere.

  1. welche methode sollte ich deiner meinung nach unter solchen umständen anwenden? Denken Sie daran, dass ich alle paar Minuten mehrere Tabellenänderungen vom Client zum Server senden und auch zwei Tabellenänderungen vom Server abrufen muss.

  2. Ich habe eine Methode gefunden, die seltsam, aber neu ist. Ist es möglich, dass ich alle ausgeführten (für bestimmte bevorzugte) gespeicherten Prozeduren im Client protokolliere und sie mit ihren Parametern in einer .sqlDatei an den Server sende und dort ausführe? Das gleiche passiert auf dem Server und wird an den Client gesendet. Denken Sie, dass dies eine einfache, aber nützliche Methode ist oder nicht?

  3. Bitte schlagen Sie mir einen nützlichen Ansatz vor, wenn Sie können. Ich danke dir sehr.

BEARBEITEN: Denken Sie daran, dass dies eine Echtzeitsynchronisation ist und dies macht es besonders. Wenn der Clientbenutzer die Tabelle verwendet, muss der Synchronisierungsvorgang mit dem Server alle paar Minuten stattfinden, damit keine der Tabellen gesperrt werden muss.

Emad Farrokhi
quelle
1
Denken Sie daran, dass diese "Black Boxes" relativ gut dokumentiert sind in Bezug auf ihre Funktionsweise, Wartung und Überwachung und was Sie tun können, um sie in häufigen (und nicht so häufigen) Fehlerszenarien zu beheben. Ich würde in Betracht ziehen, meine eigene Synchronisationsmethode fortzusetzen und Fehler in Bezug auf Randfälle zu finden und zu beheben, die die "Black Boxes" vor langer Zeit angesprochen haben, und zwar genau dann, wenn ich sehr anwendungsspezifische Bedürfnisse hatte (teilweise Synchronisation oder das Bedürfnis nach interaktive Konfliktlösung usw.).
David Spillett
@DavidSpillett: Haben Sie die Replikation in einem Echtzeitsynchronisationsprojekt erfolgreich verwendet? Mein Hauptanliegen ist die Echtzeitsynchronisation und "Sperren und Sperren".
Emad Farrokhi

Antworten:

14

Nun, ich verstehe es vielleicht nicht, aber ich versuche es zu beantworten.

Sie sagten, Sie brauchen eine Hochleistungslösung, die häufig ausgeführt wird (mindestens alle 2 Minuten), und Sie brauchen einen guten Ansatz, der schnell sein sollte, ohne zu blockieren. Aber Sie wollen kein Blackbox-System.

Anstelle eines Blackbox-Systems, das bei Millionen von Installationen mit guten Ergebnissen eingesetzt wird, versuchen Sie, das Rad erneut zu erfinden und Ihre eigene Lösung zu erstellen? Hm, klingt ein bisschen komisch.

In der Tat sind dies meine Vorschläge.

  1. Replikation, selbst wenn Sie sagten, dass Sie sie nicht verwenden werden. Es ist die einfachste und beste Lösung, die Sie dafür verwenden können. Die Replikation ist einfach einzurichten, schnell zu replizieren und Sie müssen das Rad nicht neu erfinden. Wenn Sie einfach seltsam zu sperren, können Sie versuchen , die festlegen ISOLATION LEVELzu READ_COMMITTED_SNAPSHOT. Sie können mehr darüber lesen Sie hier . Dies verbraucht einen Teil Ihrer Tempdb, aber Ihre Tabelle ist immer lesbar und schreibbar und die Replikation kann im Hintergrund funktionieren.

Siehe folgendes Beispiel:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. CDC (Change Data Capture) kann ebenfalls eine Lösung sein. Aber auf diese Weise müssen Sie fast alles selbst bauen. Und ich habe die Erfahrung gemacht, dass unter CDCbestimmten Umständen eine fragile Sache sein kann. CDCerfasst alle Daten in einer überwachten Tabelle (Sie müssen jede überwachte Tabelle manuell angeben). Danach erhalten Sie den Wert vor und den Wert nach einem INSERT, UPDATEoder DELETE. CDCDiese Informationen werden für einen bestimmten Zeitraum gespeichert (Sie können sie selbst festlegen). Der Ansatz könnte darin bestehen, CDCdiese Änderungen für bestimmte Tabellen zu überwachen und manuell in die andere Datenbank zu replizieren. CDCVerwendet übrigens auch die SQL Server-Replikation unter der Haube. ;-) Mehr darüber können Sie hier lesen .

Warnung: CDCwird nicht über DDLÄnderungen informiert. Wenn Sie also eine Tabelle ändern und eine neue Spalte hinzufügen, CDCwird die Tabelle überwacht, alle Änderungen an der neuen Spalte werden jedoch ignoriert. In der Tat zeichnet es nur NULLals Wert vor und Wert nach. Sie müssen es nach DDL-Änderungen an einer beobachteten Tabelle neu initialisieren.

  1. Die oben beschriebene Vorgehensweise entspricht in etwa der Erfassung eines Workloads mit SQL Server Profiler und dessen erneuter Ausführung in einer anderen Datenbank für einige Benchmarks. Nun könnte es funktionieren. Aber die Tatsache, dass es zu viele Nebenwirkungen gibt, ist mir ein bisschen zu schwer. Was tun Sie, wenn Sie einen Prozeduraufruf auf Ihrem Client erfassen? Führen Sie anschließend denselben Befehl in Ihrer Prinzipaldatenbank aus, der nicht mehr synchron ist. Die Prozedur wird möglicherweise ausgeführt, löscht / aktualisiert / fügt jedoch möglicherweise Zeilen ein, die in Ihrem Client nicht vorhanden waren. Oder wie gehen Sie mit mehreren Kunden mit einem Prinzip um? Ich finde das zu knifflig. Im schlimmsten Fall zerstören Sie wahrscheinlich Ihre Integrität.
  2. Eine andere Idee könnte anwendungsbasiert sein oder einen Auslöser verwenden. Abhängig davon, wie viele Tabellen synchronisiert werden sollen. Sie können alle Änderungen in eine separate Staging-Tabelle schreiben und einen SQL Server-Agent-Job alle x Minuten ausführen, um diese Zeilen in der Staging-Tabelle mit Ihrem Master zu synchronisieren. Dies kann jedoch etwas zu schwer sein, wenn Sie versuchen, (zB) 150 Tabellen zu synchronisieren. Sie würden einen großen Aufwand haben.

Nun, das sind meine 2 Cent. Hoffentlich haben Sie einen guten Überblick und vielleicht haben Sie eine Lösung gefunden, die für Sie funktioniert.

Ionic
quelle
9

Ich werde versuchen, hier einige Optionen mit Vor- und Nachteilen aufzuzählen, wenn ich sie sehe:

  1. SQL Server-Replikation - Dies ist das beste und am besten optimierte native SQL Server-Tool für diese Aufgabe. Es gibt jedoch mehrere Probleme: a. Für alle Ihre Clients, unabhängig davon, ob es sich um SQL Express-Datenbanken handelt oder nicht, benötigen Sie eine SQL Server-CAL-Lizenz. Dies kann durch die Verwendung einer Lizenz pro Prozessor vermieden werden. b. Sie können den SQL CE-Client nicht wie hier beschrieben synchronisieren. c. SQL Express oder LocalDB können nicht als Herausgeber oder Verteiler fungieren , sodass Sie auf dem Client weniger Kontrolle über den Replikationsprozess haben.
  2. Microsoft Sync Framework - scheint mir besser für kleinere Datenbanken von mobilen Apps geeignet zu sein. Es fügt Ihrer Datenbank eine Menge Tabellen hinzu und ist nicht so effizient wie die Replikation. Da es außerhalb von SQL Server als Komponente implementiert wird, ist die Konfiguration schwieriger. Ich habe keine Erfahrung damit, habe es nur ausprobiert und mich entschieden, es nicht zu benutzen.

  3. Verfolgung von Datenbankänderungen . Dies ist eine integrierte SQL Server-Funktion, mit der Sie die Nachverfolgung einschließlich Einfügungen, Aktualisierungen und Löschvorgängen ändern können. Alles andere wie das Senden und Anwenden von Änderungen, das Lösen von Konflikten usw. müssen Sie selbst codieren.

  4. Zeilenversionsspalten (Zeitstempel) Wenn Sie alle Löschvorgänge nicht zulassen (keine Synchronisierung gelöschter Datensätze), können Sie Ihre eigene Lösung nur auf der Grundlage von Zeilenversionsinformationen implementieren. Zeilenversionsspalten werden auch von SQL Server Replication verwendet, sodass Sie sie trotzdem hinzufügen müssen.
  5. CDC wie in Ionic's Antwort erwähnt - Ich habe keine Erfahrung damit, da es nur in Enterprise- oder Developer-Editionen verfügbar ist.

  6. Die Verwendung Ihres eigenen Tricks bei der Protokollierung von gespeicherten Prozeduren hängt stark von der Art Ihrer Datenbankanwendung ab. Wenn sich die Abläufe jedoch nur geringfügig unterscheiden, kann es zu einer großen Datenverwirrung kommen. Und wie würden Sie mit Konflikten umgehen?

Aus Ihrer Frage geht hervor, dass Sie nur wenige Tabellen und nicht die gesamten großen Datenbanken synchronisieren müssen. Zu diesem Zweck sollten Sie Ihre Bedürfnisse genauer analysieren, als Sie in der Frage angegeben haben, wie zum Beispiel:

  • Können Löschungen passieren und was passiert dann?
  • Können Konflikte entstehen, wie können sie verhindert und wie können sie gelöst werden?
  • Wie gehe ich mit Änderungen der Tabellenstruktur um?
  • ...

Wenn Sie irgendwann herausfinden, dass Löschvorgänge und Konflikte nicht Ihr Problem sind und sich Ihre Struktur nicht wesentlich ändert, können Sie Ihre eigene Logik schreiben, die jedoch leicht auf 1000 Codezeilen anwachsen kann.

Vojtěch Dohnal
quelle
2

Vielen Dank für Ihr Feedback.

Ich habe den Synchronisierungsprozess erfolgreich gelöst, indem ich die ausgeführten gespeicherten Prozeduren nicht als Gruppe, sondern nacheinander erfasst habe, was in meinem Fall sehr gut funktioniert hat. Da Integrität und alles sorgfältig geprüft wurden, arbeitete das System bisher in Echtzeit.

Emad Farrokhi
quelle
Toll aber kannst du bitte genauer erklären, was du getan hast. Protokollieren Sie einfach die Aufrufe der ausgeführten gespeicherten Prozeduren und speichern Sie sie in einer temporären Tabelle / einem temporären Skript, und lassen Sie dieses Skript von einem Job ausführen, der ein Feld festlegt (z. B. ein Bitfeld oder ein Datum / Uhrzeit-Feld, in dem Sie für ALLE diese Angaben machen) Datensätze, die nicht verarbeitet wurden, verarbeiten sie und aktualisieren das Bitfeld?) Ich bin froh, dass Sie Ihr Problem gelöst haben, aber Sie möchten mehr Einsicht darüber geben, was Sie getan haben, um anderen beim Lernen zu helfen?
JonH
0

Späte Antwort, aber es kann hilfreich sein, Besucher zu fädeln

Bei dem Versuch, Daten auf verschiedenen Servern zu verteilen und mithilfe von Tools von Drittanbietern ( Diff für Schemaänderungen und DataDiff für die Synchronisierung von Datenänderungen) und dem folgenden PowerShell-Skript, das zur Automatisierung des Prozesses erforderlich ist, zu lösen, stellte sich eine ähnliche Herausforderung :

#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"
}

}

Diese Methode plant den Vergleich zwischen zwei Datenbanken und synchronisiert gefundene Änderungen in Echtzeit. Hier sind einige Artikel mit schrittweisen Anleitungen:

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

Monte Chavis
quelle