Des données ne sont pas remises aux abonnés
S'il apparaît que des données ne sont pas remises aux abonnés, cela peut être dû à deux raisons principales :
Les données ne sont pas appliquées à cause d'un filtrage, du problème d'un agent ou d'une autre erreur de réplication.
Les données sont supprimées sur l'Abonné après y avoir été appliquées.
Explication
Il y a plusieurs raisons possibles pour que les données ne soient pas remises aux Abonnés :
La table est filtrée et il n'y a pas de modifications à remettre à un Abonné donné.
Un ou plusieurs agents ne s'exécutent pas ou ont échoué avec une erreur.
Un abonnement transactionnel a été initialisé sans capture instantanée, et il y a eu des modifications sur le serveur de publication depuis que la publication a été créée.
La réplication de l'exécution d'une procédure stockée pour une publication transactionnelle produit des résultats différents sur l'Abonné.
La procédure stockée INSERT utilisée par un article transactionnel comporte une condition qui n'est pas satisfaite.
Les données sont supprimées par un utilisateur, par un script de réplication ou par une autre application.
Les données sont supprimées par un déclencheur, ou un déclencheur comporte une instruction ROLLBACK.
Action de l'utilisateur
Avant d'essayer de diagnostiquer pourquoi les données ne sont pas remises aux Abonnés, nous vous recommandons d'utiliser la validation ou l'utilitaire tablediff pour vérifier que des lignes sont manquantes :
Si l'Agent de distribution ou l'Agent de fusion peut s'exécuter, déterminez si des données sont manquantes en exécutant une validation de total de contrôle binaire. Vous pouvez aussi utiliser une validation de comptage des lignes, mais cette méthode ne révèle pas les différences dans le contenu des données. Pour plus d'informations, consultez Validation des données répliquées.
Si l'Agent de distribution ou l'Agent de fusion ne peut pas s'exécuter, déterminez si des données sont manquantes en exécutant l'utilitaire tablediff. Pour des informations sur l'utilisation de cet utilitaire sur des tables répliquées, consultez Procédure : comparer les tables répliquées pour les différences (programmation de réplication).
Résolution des problèmes à l'origine de l'absence des données
Les actions suivantes résolvent les problèmes dont la liste est donnée dans la section « Explication » :
La table est filtrée et il n'y a pas de modifications à remettre à un Abonné donné.
Il est possible que les lignes manquantes sur l'Abonné n'aient pas été répliquées parce qu'elles ne correspondent pas aux critères de filtrage pour la publication. Tous les types de réplication prennent en charge les filtres statiques, et la réplication de fusion prend également en charge les filtres paramétrés et les filtres de jointure. Pour plus d'informations, consultez Filtrage des données publiées. Si un ou plusieurs articles de la publication sont filtrés, exécutez les procédures suivantes et vérifiez la valeur de la clause du filtre :
Filtre statique pour les publications de capture instantanée et transactionnelles : la colonne filter_clause renvoyée par sp_helparticle (Transact-SQL).
Filtre statique et filtre paramétré pour les publications de fusion : la colonne subset_filterclause renvoyée par sp_helpmergearticle (Transact-SQL).
Filtre de jointure pour les publications de fusion : la colonne join_filterclause renvoyée par sp_helpmergefilter (Transact-SQL).
Utilisez la clause du filtre pour déterminer si des lignes manquantes correspondent aux critères de filtrage. Par exemple, vous pouvez exécuter la clause du filtre sur une table du serveur de publication et déterminer si les données renvoyées correspondent aux données sur l'Abonné.
Un ou plusieurs agents ne s'exécutent pas ou ont échoué avec une erreur :
Si vous initialisez un abonnement, vérifiez que l'Agent de capture instantanée pour la publication s'est terminé avant d'essayer d'appliquer la capture instantanée avec l'Agent de distribution ou l'Agent de fusion. Si vous essayez d'appliquer la capture instantanée avant qu'il se termine, les erreurs suivantes se produisent : « La capture instantanée initiale de la publication '%s' n'est pas encore disponible. »
Pour la réplication transactionnelle, vérifiez que l'Agent de distribution et l'Agent de lecture du journal s'exécutent ; pour la réplication de fusion, vérifiez que l'Agent de fusion s'exécute. Pour des informations sur le démarrage de ces agents, consultez Procédure : démarrer et arrêter un Agent de réplication (SQL Server Management Studio) et Concepts des exécutables de l'agent de réplication.
Si un agent s'arrête à cause d'une erreur, affichez les détails de l'erreur de l'agent pour en déterminer la cause sous-jacente. Pour des informations sur l'affichage des détails d'une erreur pour l'Agent de capture instantanée et l'Agent de lecture du journal, consultez Procédure : afficher des informations et effectuer des tâches pour les agents associés à une publication (moniteur de réplication). Pour des informations sur l'Agent de distribution et l'Agent de fusion, consultez Procédure : afficher des informations et effectuer des tâches pour les agents associés à un abonnement (Moniteur de réplication). Si l'erreur continue de se produire, augmentez le facteur de journalisation de l'agent et spécifiez un fichier de sortie pour le journal. En fonction du contexte de l'erreur, cette action peut fournir des pistes conduisant à l'erreur et/ou à d'autres messages d'erreur. Pour plus d'informations, consultez Agents de réplication (résolution des problèmes).
Les problèmes d'autorisations et les violations de contrainte figurent parmi les erreurs courantes qui provoquent la non-remise de données. Pour plus d'informations sur les problèmes d'autorisations, consultez Des problèmes de sécurité empêchent les données d'être répliquées. Les violations de contrainte empêchent des lignes d'être insérées sur l'Abonné.
Pour la réplication transactionnelle, les violations de contrainte sont traitées comme des erreurs ; par défaut, elles provoquent l'arrêt de la synchronisation de l'Agent de distribution si elles sont rencontrées (pour des informations sur la façon d'ignorer ces erreurs, consultez Omission des erreurs lors de la réplication transactionnelle). Pour la réplication de fusion, les violations de contrainte sont traitées comme des conflits ; elles sont journalisées mais ne provoquent pas l'arrêt de la synchronisation de l'Agent de fusion. Pour les deux types de réplication, les violations de contrainte peuvent conduire à la non-convergence si une insertion, une mise à jour ou une suppression qui a réussi sur un nœud échoue sur un autre.
Quand une table est publiée, les options de schéma par défaut spécifient que les contraintes de clé étrangère et les contraintes de validation doivent être créées dans la base de données d'abonnement avec l'option NOT FOR REPLICATION activée. Si votre application requiert d'autres paramètres pour les contraintes, modifiez les options de schéma. Pour plus d'informations, consultez Procédure : spécifier des options de schéma (SQL Server Management Studio) et Procédure : spécifier des options de schéma (programmation Transact-SQL de la réplication).
Un abonnement transactionnel a été initialisé sans capture instantanée, et il y a eu des modifications sur le serveur de publication depuis que la publication a été créée.
Si vous activez l'initialisation d'une publication à partir d'une sauvegarde, les modifications apportées aux tables publiées sont suivies dans le journal de la base de données de publication dès que la publication est créée. Quand un abonnement est initialisé, les modifications en attente sont remises à l'Abonné tant qu'elles restent disponibles dans la base de données de distribution.
Contrairement à l'initialisation à partir d'une sauvegarde, si vous initialisez un abonnement à l'aide de l'option Prise en charge de la réplication uniquement, vous-même ou votre application devez vérifier que les données et le schéma sont correctement synchronisés au moment où vous ajoutez l'abonnement. Si par exemple il y a une activité sur le serveur de publication entre le moment où les données et le schéma sont copiés vers l'Abonné et le moment auquel l'abonnement est ajouté, les modifications résultant de cette activité peuvent ne pas être répliquées vers l'Abonné.
Pour plus d'informations, consultez Initialisation d'un abonnement transactionnel sans capture instantanée.
La réplication de l'exécution d'une procédure stockée pour une publication transactionnelle produit des résultats différents sur l'Abonné.
Si vous répliquez l'exécution d'une procédure stockée, la définition de la procédure est répliquée vers l'Abonné quand l'abonnement est initialisé ; quand la procédure est exécutée sur le serveur de publication, la réplication exécute la procédure correspondante sur l'Abonné. Pour plus d'informations, consultez Publication de l'exécution de procédures stockées dans la réplication transactionnelle.
Si la procédure stockée effectue une action différente sur l'Abonné ou agit sur des données différentes de celles du serveur de publication, une non-convergence peut se produire. Supposons une procédure qui effectue un calcul puis insère des données basées sur ce calcul. Si l'Abonné est filtré de telle façon que le calcul sur l'Abonné est basé sur des données différentes, le résultat inséré sur l'Abonné peut être différent ou l'insertion peut ne pas se faire du tout.
La procédure stockée INSERT utilisée par un article transactionnel comporte une condition qui n'est pas satisfaite.
Par défaut, la réplication transactionnelle utilise un ensemble de procédures stockées pour propager les modifications vers les Abonnés. Vous pouvez aussi personnaliser ces procédures pour y inclure la logique métier requise par votre application. Pour plus d'informations, consultez Spécification du mode de propagation des modifications des articles transactionnels. Si la procédure stockée INSERT comprend une condition dans sa logique qui n'est pas satisfaite, l'insertion ne se fait pas. Supposons une procédure qui est personnalisée pour vérifier une certaine valeur dans une table (Table A) sur l'Abonné avant d'autoriser une insertion dans une autre table (Table B). Si la valeur n'est pas disponible dans la table A à cause d'une erreur ou parce que les données n'ont pas encore été répliquées vers cette table, la ligne attendue est manquante dans la Table B.
Les données sont supprimées par un utilisateur, par un script de réplication ou par une autre application :
Si vous voulez permettre aux utilisateurs de supprimer des données sur l'Abonné, utilisez la réplication de fusion, la réplication transactionnelle avec des abonnements pouvant être mis à jour ou la réplication transactionnelle d'égal à égal. Les suppressions sont propagées vers le serveur de publication et les données sur le serveur de publication et sur l'Abonné vont finalement converger. Pour plus d'informations, consultez Présentation de la réplication de fusion et Types de publication pour la réplication transactionnelle.
Si vous voulez empêcher les utilisateurs de supprimer des données sur l'Abonné, créez un déclencheur pour chaque table qui contient le mot ROLLBACK et utilisez l'option NOT FOR REPLICATION (qui empêche un déclencheur de s'exécuter quand un agent de réplication effectue une opération). Par exemple :
USE AdventureWorks GO CREATE TRIGGER prevent_user_dml ON Person.Address FOR INSERT, UPDATE, DELETE NOT FOR REPLICATION AS ROLLBACK
Pour plus d'informations, consultez CREATE TRIGGER (Transact-SQL) et Contrôle des contraintes, des identités et des déclencheurs avec l'option NOT FOR REPLICATION.
La réplication vous permet d'exécuter des scripts avant et après l'application de la capture instantanée et au cours de la synchronisation. Les paramètres @pre_snapshot_script et @post_snapshot_script de sp_addpublication et sp_addmergepublication vous permettent de spécifier des scripts à exécuter avant et après l'application de la capture instantanée. Pour plus d'informations, consultez Exécution de scripts avant et après l'application de la capture instantanée. La procédure stockée sp_addscriptexec vous permet d'exécuter un script au cours du processus de synchronisation. Pour plus d'informations, consultez Procédure : exécuter des scripts pendant la synchronisation (programmation Transact-SQL de la réplication).
Ces scripts sont généralement utilisés pour des tâches d'administration, telles que l'ajout de noms de connexion sur l'Abonné. Si les scripts sont utilisés pour supprimer des données sur un Abonné qui doit être traité en lecture seule, l'administrateur doit vérifier que cela n'aboutit pas à une non-convergence.
Les données sont supprimées par un déclencheur, ou un déclencheur comporte une instruction ROLLBACK.
Les déclencheurs sur l'Abonné doivent être gérés correctement, de façon à ce qu'ils ne provoquent pas une non-convergence ou d'autres problèmes :
Les déclencheurs doivent seulement provoquer des modifications de données sur l'Abonné si vous utilisez la réplication de fusion, la réplication transactionnelle avec des abonnements pouvant être mis à jour ou la réplication transactionnelle d'égal à égal. Pour plus d'informations, consultez Présentation de la réplication de fusion et Types de publication pour la réplication transactionnelle.
Dans de nombreux cas, les déclencheurs doivent utiliser l'option NOT FOR REPLICATION. Si un déclencheur comprend une instruction ROLLBACK et que ce déclencheur n'utilise pas l'option NOT FOR REPLICATION, les lignes qui ont été répliquées vers un Abonné peuvent ne pas être appliquées.
Pour la réplication transactionnelle, il y a d'autres considérations concernant le paramètre XACT_ABORT et l'utilisation des instructions COMMIT et ROLLBACK dans un déclencheur. Pour plus d'informations, consultez la section « Déclencheurs » de Considérations pour la réplication transactionnelle.