La synchronisation des données de la table dans les bases de données
J'ai une table qui enregistre sa ligne d'insertion/mise à jour date et l'heure sur un champ.
Je veux synchroniser les données dans ce tableau à un autre tableau sur un autre serveur de base de données. Deux db serveurs ne sont pas connectés et que la synchronisation est une façon (maître/esclave). A l'aide du tableau des déclencheurs n'est pas adapté
Mon flux de travail:
- - Je utiliser un mondial last_sync_date paramètre de requête et de tableau de Maître pour les
le changement de/enregistrements insérés - Sortie les lignes obtenues à xml
- Parse le xml et mettre à jour le tableau de l'Esclave à l'aide de mises à jour et des inserts
La complexité du problème augmente lorsque vous traitez avec des enregistrements supprimés de la table Maître. Pour attraper les enregistrements supprimés je pense que je dois maintenir une table de journal pour les déjà inséré des dossiers et l'utilisation de sql "NON". Cela devient un problème de performance lorsque le traitement de grands ensembles de données.
Ce qui serait une alternative de flux de travail traitant de ce scénario?
- Et la base de données que vous utilisez? (maître et de l'esclave?)
- Actuellement à l'aide de MsSql pour maître et mysql en tant qu'esclave, donc je ne pense pas qu'une base de données spécifique de la solution permettra d'
- Jetez aussi un oeil à cette légèrement lien en.wikipedia.org/wiki/CAP_theorem
- La formulation de la question ne correspond pas à son contenu et est suspect pour moi. Si les serveurs ne sont pas connecté, alors votre seule option est un fichier d'exportation vers un disque amovible et transférer les données de cette façon, sinon ils sont reliés d'une certaine manière. Connecté inclut le web, vous avez des options comme les déclencheurs disponibles pour vous. La seule raison pour laquelle vous ne devriez pas être en mesure de les utiliser est un DBA de le nier et je n'ai jamais rencontré un administrateur de base qui permettraient de refuser l'utilisation d'un déclencheur si elle s'est avérée bénéfique. Restrictions de pare-feu et peut être surmonté que si vous faites cela de manière légitime.
- Je me sens pour vous que j'ai offert la solution d'un message de la file d'attente parce qu'il a marqués de la question printemps-lot. À mon humble avis, Soit il devrait l'utilisation réelle de la réplication ou la file d'attente de messages. Il a également inquiets au sujet d'un problème de performance qui n'est même pas un problème (c'est à dire: PAS DE problème).
- Génial! J'ai fait un commentaire sarcastique 3 jours concernant les machines n'étant pas "connecté", plus d'exagérer les choses. S'il vous plaît dites-moi ce que vous avez reconstitué dans votre tête qui permettrait d'invoquer le hasard commentaire.
- Quoi que je recommande à ce mec... il a de gros problèmes 😉
- avez-vous jamais lu sur le non-sens de mettre déclencheurs à l'aide de db liens? Qu'advient-il si la connexion va et qu'ils ont invalidé? Cette tâche de synchronisation, comme clairement indiqué dans la question, doit être un processus qui ne sera pas nuire à l'entreprise.
- Le processus décrit sur la question est sur l'air, nous l'utilisons avec succès; mais puisque c'est un système d'héritage, j'ai ouvert cette question. Ainsi, le problème de performance "est" un problème.
- Je viens vous donner de la merde. Pour le
NOT IN
vous avez juste à faire un temporaire id de tableau. Voir ma réponse: stackoverflow.com/questions/2861230/... et stackoverflow.com/a/12927312/318174 . Le seul problème est qu'il semble que vous ne voulez pas le faire toute db changements... pouvez-vous faire tmp id de tableau? - Je suis vraiment heureux avec votre proposition d'aide de files de messages. Je l'ai mentionné un "journal de table" dans la question, c'est le tmp de l'id de tableau.
- Où ai-je suggérer à l'aide de déclencheurs pour cette solution? Oh, c'est vrai, je n'ai pas. Sérieusement l'homme, y renoncer.
Vous devez vous connecter pour publier un commentaire.
Il sonne comme vous avez besoin d'un message transactionnel de la file d'attente.
La façon dont cela fonctionne est simple. Lorsque vous mettez à jour le maître db vous pouvez envoyer un message à l'agent de messages (quel que soit le jour), ce qui peut aller à n'importe quel nombre de files d'attente. Chaque esclave db peut avoir sa propre file d'attente et parce que la file d'attente de préserver l'ordre, le processus devrait finalement synchroniser correctement (ironiquement, c'est en quelque sorte la façon dont la plupart des SGBDR ne réplication interne).
Pense que le Message de la File d'attente comme une sorte de SCM changement de liste ou de patch-liste de base de données. Qui est pour la plupart le même (ou à peu près la même) les instructions SQL envoyée à maître doit être répliqué dans les autres bases de données par la suite. Ne vous inquiétez pas de perdre des messages comme la plupart des files d'attente de messages de soutien de la durabilité et de transactions.
Je vous recommande de regarder printemps-amqp et/ou printemps-intégration surtout depuis que vous avez marqués de cette question avec le printemps-lot.
En fonction de vos commentaires:
BTW votre préoccupation de
NOT IN
être un problème de performance n'est pas très bonne car il y a une pléthore de solutions de rechange, mais compte tenu de votre ne souhaitant pas faire les DB des choses spécifiques (comme les déclencheurs et la réplication), je me sens encore un message de la file d'attente est votre meilleure option.EDIT - Non MQ route
Depuis que je vous ai donné un moment difficile de demander à cette quesiton je vais continuer à essayer de l'aider.
En plus de la file d'attente de messages, vous pouvez faire une sorte de fichier XML, comme vous, nous avons essayé avant. LA CARACTÉRISTIQUE ESSENTIELLE dont vous avez besoin dans le schéma de CRÉER une colonne de type TIMESTAMP sur votre base de données maître, de sorte que vous pouvez faire le traitement par lot alors que le système est prêt à fonctionner (sinon, vous devrez arrêter le système). Maintenant, si vous suivez cette voie, vous voudrez
SELECT * WHERE CREATE_TIME < ?
est inférieure à l'heure actuelle. Fondamentalement, votre seulement obtenir l'lignes à un instantané.Maintenant sur votre autre base de données pour le supprimer de votre va supprimer les lignes par
inner joining
sur un ID de tableau mais avec!=
(qui est, vous pouvez utiliser des JOINTURES au lieu de ralentirNOT IN
). Heureusement, vous avez seulement besoin de tous lesids
pour supprimer et pas les autres colonnes. Les autres colonnes, vous pouvez utiliser un delta en fonction de la mise à jour l'horodatage de la colonne (pour la mise à jour, et de créer des alias insert).Je ne suis pas sûr de la solution. Mais j'espère que ces liens peuvent vous aider.
http://knowledgebase.apexsql.com/2007/09/how-to-synchronize-data-between.htm
http://www.codeproject.com/Tips/348386/Copy-Synchronize-Table-Data-between-databases
Ont un coup d'oeil à Oracle GoldenGate:
SymmetricDS:
Jonquille Réplicateur:
Pourquoi ne pas simplement ajouter une colonne de type TIMESTAMP qui indique la dernière mise à jour/insérer/supprimer des temps? Puis ajouter la suppression de la colonne -- ie. marque de la ligne comme supprimé au lieu de la supprimer immédiatement. Le supprimer après avoir exporté la suppression de l'action.
Dans le cas où vous ne pouvez pas modifier le schéma d'utilisation dans une application existante:
Ne pouvez-vous pas utiliser des déclencheurs à tous? Comment environ une seconde ("caché") le tableau qui est renseignée avec tous les insert/update/delete et qui constituent le contenu de la prochaine xml généré fichier d'exportation? C'est un concept commun: une histoire (ou "log")) tableau: il aurait sa propre progression colonne id qui peut être utilisé comme un marqueur d'exportation.
Question très intéressante.
En mai cas j'ai eu assez de RAM pour charger tous les id de maître et de l'esclave tables de diff eux.
Si l'id dans la table de maître sont séquentiels vous essayez de peut maintenir un ensemble de pleine remplie de plages dans la table de maître (plages avec tous les codes utilisés, sans blancs, comme 100,101,102,103).
Pour trouver supprimé l'ids sans charger l'ensemble d'entre eux à la mémoire vous pouvez exécuter la requête SQL pour compter le nombre d'enregistrements avec des
id >= full_region.start and id <= full_region.end
pour chaque plein rempli de la région. Si le résultat de la requête== (full_region.end - full_region.end) + 1
cela signifie tous les records dans la région sont pas supprimé. Autrement - région de split en 2 parties et faire la même vérification pour deux d'entre eux (dans beaucoup de cas, seul un côté contient enlevé des dossiers).Après une certaine longueur de la plage (environ 5000 je crois), il sera plus rapide à charger tous les présents de l'ids et de vérification pour les absents à l'aide de Set.
Il y a aussi un sens à la charge de tous les codes de la mémoire pour un lot de petite taille (10 à 20 dossiers) régions.
Faire un tableau de l'historique de la table qui doit être synchronisée (en fait un double de cette table, avec quelques champs supplémentaires peut-être) et insérer l'ensemble de la ligne chaque fois que quelque chose est inséré mis à jour, supprimé dans la table active.
Écrire un Spring batch de synchroniser les données de l'Esclave de la machine, basé sur l'histoire de la table de champs supplémentaires
espère que cela aide..
Une option pour permettre à des suppressions dans votre flux de travail actuel:
Dans le cas où le déclenchement de restriction est limitée à des déclencheurs avec des références dans les bases de données, une solution possible au sein de votre flux de travail actuel serait de créer un helper table dans votre base de données pour stocker uniquement les identifiants uniques des lignes supprimées (ou quelle que soit la clé unique permettrait de vous la plus efficace de supprimer vos lignes supprimées).
Ces identifiants doivent être inséré par un déclencheur sur votre table de maître sur supprimer.
En utilisant le même mécanisme que votre insert/mises à jour, créer une tâche à la suite de votre insertions et mises à jour. Vous pouvez exporter votre table d'assistance au format xml, comme vous l'avez noté dans votre flux de travail actuel.
Cette tâche, il suffit de supprimer les lignes de l'esclave de la table, puis supprimez toutes les données de votre assistant tableau suivant l'achèvement de la tâche. Journal des erreurs de la tâche, de sorte que vous pouvez résoudre ce problème puisqu'il n'y a pas de piste d'audit.
Si votre base de données est une opération de vidage du journal, tout navire qui un.
Il est possible avec MySQL et devrait être possible avec PostgreSQL.
Je suis d'accord avec l'autre commentaire, ce qui requiert l'utilisation de déclencheurs. Je pense qu'un autre tableau doit contenir l'historique de vos requêtes sql. Voir cette réponse sur l'utilisation de 2008 a élargi les événements... Ensuite, vous pouvez obtenir l'ensemble de sql, et de stocker le résultat de la requête dans la table historique. Son jusqu'à vous si vous voulez le stocker en tant que requête mysql ou mssql requête.
Voici mon point de vue. Avez-vous vraiment besoin pour faire face à cela? Je suppose que l'esclave est à des fins de reporting. Donc la question que je voudrais poser est de savoir comment jusqu'à ce jour, devrait-il être? Est-ce ok si les données sont un jour? Prévoyez-vous d'une nuit d'actualisation?
Si oui, oubliez cette synchronisation en ligne, téléchargez le plein de tables; le navire à la base de données mysql et des lots de charger. Le temps de traitement peut être beaucoup plus rapide que vous le pensez.