Synchronisation de deux bases de données dans SQL Server


16

J'ai deux bases de données SQL Server. L'un est client (application Windows) et le second est sur le serveur. Je veux synchroniser ces deux bases de données de temps en temps (par exemple toutes les 2 minutes!).

J'ai lu différentes méthodes de synchronisation comme la réplication, l'horodatage, les tables de journal à l'aide de déclencheurs, Microsoft Sync Framework et ainsi de suite.

En fait, je n'aime pas utiliser une méthode de synchronisation qui pourrait être une boîte noire (comme la réplication) parce que je ne veux pas que les tables spécifiques à SQL Server soient bloquées pendant que je les mets à jour et les synchronise avec le serveur.

  1. quelle méthode pensez-vous que je devrais utiliser dans de telles circonstances? N'oubliez pas que toutes les quelques minutes, je dois envoyer plusieurs modifications de table du client au serveur et récupérer également deux modifications de table du serveur.

  2. J'ai trouvé une méthode étrange mais nouvelle. Est-il possible que j'enregistre toutes les procédures stockées exécutées (pour des préférences spécifiques) dans le client et les envoie avec leurs paramètres dans un .sqlfichier au serveur et les y exécute? La même chose se produira sur le serveur et sera envoyée au client. Pensez-vous qu'il s'agit d'une méthode simple mais utile ou non?

  3. veuillez me suggérer toute approche utile si vous le pouvez. Merci beaucoup.

EDIT: N'oubliez pas qu'il s'agit d'une synchronisation en temps réel et que cela la rend spéciale. Cela signifie que lorsque l'utilisateur client utilise la table, le processus de synchronisation avec le serveur doit avoir lieu toutes les quelques minutes, donc aucune des tables ne doit être verrouillée.


1
N'oubliez pas que ces «boîtes noires» sont relativement bien documentées en ce qui concerne leur fonctionnement, leur maintenance et leur surveillance, et ce que vous pouvez faire pour les corriger dans des scénarios de défaillance courants (et moins courants). J'envisagerais de rouler ma propre méthode de synchronisation et de devoir trouver et corriger les bugs liés aux cas marginaux que les "boîtes noires" ont traités il y a longtemps si et seulement si j'avais des besoins très spécifiques à l'application (synchronisation partielle, ou besoin de user- résolution interactive des conflits, etc.).
David Spillett

@DavidSpillett: Avez-vous utilisé la réplication dans un projet de synchronisation en temps réel avec succès? Ma principale préoccupation est la synchronisation en temps réel et le "verrouillage et le blocage".
Emad Farrokhi

Réponses:


14

Eh bien, je ne comprends peut-être pas, mais j'essaie d'y répondre.

Vous avez dit que vous avez besoin d'une solution hautes performances qui fonctionne souvent (minimum toutes les 2 minutes) et vous avez besoin d'une bonne approche qui devrait être rapide sans verrouillage. Mais vous ne voulez pas d'un système de boîte noire.

Au lieu d'un système de boîte noire, qui est utilisé sur des millions d'installations avec de bons résultats, vous essayez de réinventer la roue et de construire votre propre solution? Hm, ça sonne un peu bizarre.

En fait, ce sont mes suggestions.

  1. Réplication même si vous avez dit que vous ne l'utiliseriez pas. C'est la solution la plus simple et la meilleure que vous puissiez utiliser pour cela. La réplication est facile à configurer, à répliquer rapidement et vous n'avez pas à réinventer la roue. Si vous êtes bizarre à propos du verrouillage, vous pouvez essayer de le régler ISOLATION LEVELsur READ_COMMITTED_SNAPSHOT. Vous pouvez en lire plus ici . Cela utilisera une partie de votre tempdb, mais votre table est toujours en lecture et en écriture et la réplication peut fonctionner en arrière-plan.

Voir l'exemple ci-dessous:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. CDC (Change Data Capture) peut également être une solution. Mais de cette façon, vous devez construire presque tout par vous-même. Et j'ai fait l'expérience qui CDCpeut être une chose fragile dans certaines circonstances. CDCcapturera toutes les données d'une table surveillée (vous devez spécifier manuellement chaque table surveillée). Ensuite, vous obtiendrez la valeur avant et la valeur après un INSERT, UPDATEou DELETE. CDCretiendra ces informations pendant un certain temps (vous pouvez les spécifier vous-même). L'approche pourrait être d'utiliser CDCsur certaines tables que vous devez surveiller et répliquer manuellement ces modifications dans l'autre base de données. Soit dit en passant, CDCutilise également la réplication SQL Server sous le capot. ;-) Vous pouvez en savoir plus ici .

Avertissement: CDCne sera pas au courant des DDLchangements. Cela signifie que si vous modifiez une table et ajoutez une nouvelle colonne, CDCelle surveillera la table mais ignorera toutes les modifications apportées à la nouvelle colonne. En fait, il n'enregistre NULLque la valeur avant et la valeur après. Vous devez le réinitialiser après DDL-Change à une table surveillée.

  1. La façon dont vous avez décrit ci-dessus est quelque chose comme capturer une charge de travail à l'aide de SQL Server Profiler et l'exécuter à nouveau sur une autre base de données pour certains tests de performance. Ça pourrait bien marcher. Mais le fait qu'il y ait trop d'effets secondaires est un peu trop lourd pour moi. Que faites-vous si vous capturez un appel de procédure sur votre client. Après avoir exécuté la même commande dans votre base de données principale car elle n'est pas synchronisée? La procédure peut s'exécuter, mais elle peut supprimer / mettre à jour / insérer des lignes qui n'étaient pas présentes dans votre client. Ou comment gérez-vous plusieurs clients avec un seul principe. Je pense que c'est trop délicat. Dans le pire des cas, vous détruisez probablement votre intégrité.
  2. Une autre idée pourrait être basée sur l'application ou en utilisant un déclencheur. Selon le nombre de tables que vous souhaitez synchroniser. Vous pouvez écrire toutes les modifications dans une table de transfert distincte et exécuter un travail de l'Agent SQL Server toutes les x minutes pour synchroniser ces lignes de la table de transfert avec votre maître. Mais cela peut être un peu trop lourd si vous essayez de synchroniser (par exemple) 150 tables. Vous auriez un gros frais généraux.

Eh bien, ce sont mes 2 cents. J'espère que vous avez une bonne vue d'ensemble et que vous avez peut-être trouvé une solution qui vous convient.


9

Je vais essayer d'énumérer ici quelques options avec des avantages et des inconvénients au fur et à mesure que je les perçois:

  1. Réplication SQL Server - il s'agit de l'outil SQL Server natif le meilleur et le plus optimisé pour cette tâche. Mais il y a plusieurs problèmes: a. pour tous vos clients, qu'ils soient ou non des bases de données SQL Express, vous aurez besoin d'une licence CAL SQL Server. Cela peut être évité en utilisant une licence par processeur. b. Vous ne pouvez pas synchroniser le client SQL CE comme indiqué ici . c. SQL Express ou LocalDB ne peut pas agir en tant qu'éditeur ou distributeur , vous avez donc moins de contrôle sur le client sur le processus de réplication.
  2. Microsoft Sync Framework - me semble plus adapté aux petites bases de données d'applications mobiles. Il ajoute un grand nombre de tables à votre base de données et n'est pas aussi efficace que la réplication. Comme il est implémenté en dehors de SQL Server en tant que composant, il sera plus difficile à configurer. Je n'en ai aucune expérience, je l'ai seulement essayé et j'ai décidé de ne pas l'utiliser.

  3. Suivi des modifications de la base de données . Il s'agit d'une fonction SQL Server intégrée qui vous permet de modifier le suivi, y compris les insertions, les mises à jour et les suppressions. Tout le reste, comme l'envoi et l'application de modifications, la résolution de conflits, etc., vous devrez vous coder.

  4. Colonnes Rowversion (horodatage) Si vous n'autorisez pas toutes les suppressions (pas de synchronisation des enregistrements supprimés) - vous pouvez implémenter votre propre solution uniquement sur la base des informations de rowversion. Les colonnes Rowversion sont également utilisées par la réplication SQL Server, vous devrez donc les ajouter de toute façon.
  5. CDC comme mentionné dans la réponse d'Ionic - je n'ai aucune expérience avec cela, car il n'est disponible que dans les éditions Enterprise ou Developer.

  6. L'utilisation de votre propre astuce avec la journalisation des procédures stockées exécutées - dépend beaucoup de la nature de votre application de base de données. Mais lorsque les procédures diffèrent peu, vous pouvez obtenir un gros gâchis de données. Et comment feriez-vous face aux conflits?

D'après votre question, il semble que vous ayez besoin de synchroniser seulement quelques tables et non toutes les grandes bases de données. À cette fin, vous devez analyser vos besoins plus en détail que ce que vous avez spécifié dans la question, comme:

  • Les suppressions peuvent-elles se produire et que se passe-t-il ensuite?
  • Les conflits peuvent-ils se produire, comment les prévenir et comment les résoudre?
  • Comment vais-je gérer les changements de structure de table?
  • ...

Si vous finissez par découvrir que les suppressions et les conflits ne sont pas votre problème et que votre structure ne changera pas beaucoup, vous pouvez envisager d'écrire votre propre logique, mais elle peut facilement atteindre 1 000 lignes de code.


2

Merci à tous pour vos commentaires.

J'ai réussi à résoudre le processus de synchronisation en capturant les procédures stockées exécutées non pas en tant que groupe mais une par une, ce qui fonctionnait très bien dans mon cas. L'intégrité et tout étant soigneusement pris en compte, le système fonctionne jusqu'à présent en temps réel.


Très bien mais pouvez-vous expliquer plus en détail ce que vous avez fait. Consignez-vous simplement les appels des procédures stockées qui ont été exécutées et stockez-les dans une table / script temporaire et demandez à un travail d'exécuter ce script et de définir un champ (tel qu'un champ de bits ou un champ datetime où vous dites pour TOUS ces les enregistrements qui n'ont pas été traités les traitent et mettent à jour le champ de bits?) Je suis content que vous ayez résolu votre problème, mais vous devez donner plus d'informations sur ce que vous avez fait pour aider les autres à apprendre?
JonH

0

Réponse tardive, mais il pourrait être utile d'enfiler les visiteurs

J'ai eu un défi similaire à essayer de distribuer des données sur différents serveurs et à le résoudre en utilisant des outils tiers ( Diff pour les modifications de schéma et DataDiff pour la synchronisation des modifications de données) et en suivant le script PowerShell requis pour automatiser le processus:

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

}

Cette méthode planifie la comparaison entre deux bases de données et synchronise les modifications trouvées en temps réel. Voici quelques articles proposant des instructions étape par étape:

https://solutioncenter.apexsql.com/automatically-compare-and-synchronize-sql-server-data/ https://solutioncenter.apexsql.com/how-to-automatically-keep-two-sql-server-database- schémas synchronisés /

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.