Comment configurer et dépanner le paramètre SubscriptionStreams du Agent de distribution dans SQL Server
Version du produit d’origine : SQL Server (toutes les versions prises en charge)
Numéro de la base de connaissances d’origine : 953199
Cet article fournit plus d’informations sur le paramètre SubscriptionStreams
, les bonnes pratiques lors de l’utilisation de ce paramètre et la résolution des problèmes associés.
Introduction
Le paramètre SubscriptionStreams
peut être utilisé pour contrôler le nombre de connexions. Dans une réplication transactionnelle dans Microsoft SQL Server, vous pouvez utiliser le paramètre pour activer plusieurs connexions que le Agent de distribution utilise pour appliquer des lots de modifications en parallèle à un Abonné. Cette opération améliore considérablement le débit de réplication. En même temps, l’Agent de distribution peut conserver la plupart des mêmes caractéristiques transactionnelles que lorsque le Agent de distribution utilise une seule connexion pour appliquer les modifications. Si l’une des connexions ne parvient pas à s’exécuter ou à valider, toutes les connexions abandonnent le lot actuel et l’agent utilise un flux unique pour réessayer les lots ayant échoué. Avant la fin de cette phase de nouvelle tentative, il peut y avoir des incohérences transactionnelles temporaires sur l’Abonné. Une fois que les lots ayant échoué ont été correctement commités, l’Abonné est ramené à un état de cohérence transactionnelle.
Lorsque vous spécifiez une valeur supérieure ou égale à 2 pour le paramètre SubscriptionStreams
, l’ordre dans lequel les transactions sont reçues sur l’Abonné peut différer de l’ordre dans lequel elles ont été effectuées sur le serveur de publication. Si ce comportement provoque des violations de contraintes pendant la synchronisation, vous devez utiliser l’option NOT FOR REPLICATION
pour désactiver l’application des contraintes pendant la synchronisation. Pour plus d’informations, consultez Contrôler le comportement des déclencheurs et des contraintes dans la synchronisation.
Facteurs à prendre en compte avant d’activer SubscriptionStreams
SubscriptionStreams
prend principalement en charge la latence du serveur de distribution à l’abonné. Par conséquent, avant de décider d’opter pour SubscriptionStreams
, assurez-vous que vous rencontrez bien une latence entre le serveur de distribution et l’abonné. Vous pouvez utiliser des jetons de suivi dans le Moniteur de réplication ou Analyseur de performances compteurs comme SQLServer :Replication Dist.>Dist :Delivery Latency pour avoir une idée du niveau de latence.
La latence entre le serveur de distribution et l’abonné peut être due à de nombreuses raisons telles que, mais sans s’y limiter, les suivantes :
- Blocage au niveau du serveur de distribution ou de l’abonné
- Tout goulot d’étranglement, au niveau du serveur de distribution ou de l’abonné, comme les lecteurs de disque lents, la bande passante réseau lente et les statistiques obsolètes
- Transactions en bloc provenant de Publisher
- Le taux de transactions entrantes à partir du serveur de publication est trop élevé
- Déclencheurs ou index inutiles dans la base de données abonnée
L’administrateur de base de données (DBA) doit passer un appel et tester s’il SubscriptionStreams
va l’aider ou non. Par exemple, en cas de blocage sur l’Abonné, l’augmentation du nombre de connexions simultanées n’aidera pas, mais pourrait aggraver la situation. Alors que dans des situations telles que le taux de transactions entrantes de Publisher est trop élevé et que vous pensez qu’un seul thread pour le Agent de distribution est incapable de faire face à la charge entrante, vous pouvez envisager d’augmenter la valeur du paramètre SubscriptionStreams
à >=2. Cela peut également être utile dans les situations de réseau lent et de disque lent. Dans l’idéal, la valeur maximale de ce paramètre est 64, mais la valeur recommandée (ou une bonne valeur pour commencer) est égale au nombre de processeurs physiques au niveau de la destination (Abonné).
Comment configurer le paramètre SubscriptionStreams
SubscriptionStreams
est l’un de ces paramètres qui n’est pas visible dans Agent de distribution Profil dans le Moniteur de réplication. Vous pouvez spécifier une valeur pour ce paramètre d’agent à l’aide @subscriptionstreams
de sp_addsubscription (Transact-SQL) ou ajouter ce paramètre à la section de commande de travail de l’agent de distribution à l’aide de la procédure suivante :
Ouvrez le Moniteur de réplication, développez Mon serveur de publication, puis sélectionnez votre composition dans la fenêtre du volet gauche. Dans la fenêtre du volet droit, sous la section Tous les abonnements , vous verrez la liste de tous les abonnés à cette publication.
Cliquez avec le bouton droit sur l’Abonné que vous souhaitez activer le paramètre
SubscriptionStreams
, puis sélectionnez Afficher les détails. Une nouvelle fenêtre s’affiche avec les détails de la session Agent de distribution.Dans cette nouvelle fenêtre, sélectionnez Action dans la barre de menus en haut, puis Agent de distribution Propriétés du travail. La fenêtre Propriétés du travail s’ouvre pour le Agent de distribution.
Sélectionnez Étapes dans la fenêtre du volet gauche, puis sélectionnez Exécuter l’agent dans la fenêtre du volet droit, puis sélectionnez Modifier. Une nouvelle fenêtre s’affiche.
Faites défiler jusqu’à la fin de la section de commande (tout à droite) et ajoutez ce paramètre -SubscriptionStreams 6.
Enregistrez les paramètres et redémarrez le travail Agent de distribution. Un redémarrage de Agent de distribution est nécessaire pour implémenter les modifications.
Remarque
Dans l’exemple ci-dessus, SubscriptionStreams
est défini sur 6, ce qui signifie que nous recherchons six connexions parallèles pour Agent de distribution sur l’Abonné. Vous pouvez définir ce nombre en fonction de votre environnement et de vos tests.
Détermination du nombre de flux
Vous pouvez remarquer des améliorations des performances à l’aide du paramètre SubscriptionStreams
. S’il y a une amélioration, l’amélioration peut être nominale. Il est difficile de déterminer le type d’amélioration des performances que chaque sous-système de disque sur le marché fournira à l’aide SubscriptionStreams
de . Par conséquent, nous vous recommandons de préparer un environnement de test qui simule l’environnement de production. Vous pouvez tester des scénarios qui utilisent SubscriptionStreams
à l’aide de différentes valeurs de configuration et d’un scénario qui n’utilise SubscriptionStreams
pas .
Nous vous recommandons d’effectuer des tests de charge sur la publication et l’abonnement pour déterminer les améliorations de performances que vous pouvez obtenir à l’aide SubscriptionStreams
de .
Vous devez effectuer le test de la base de référence des performances pour comprendre le débit attendu du sous-système de disque. Avant d’effectuer chaque test, appliquez de nombreuses modifications pour créer une charge sur le serveur de publication. Lors de la création de la charge, assurez-vous que Agent de distribution ne s’exécute pas. Lorsque la réplication présente une latence suffisante, exécutez la Agent de distribution pour tester les performances des configurations suivantes :
- N’utilisez pas le paramètre
SubscriptionStreams
. - Définissez la valeur de
SubscriptionStreams
pour qu’elle soit égale au nombre de processeurs sur le serveur. Par exemple, si le serveur a huit processeurs, définissez la valeur surSubscriptionStreams
8. - Spécifiez différentes valeurs pour afin
SubscriptionStreams
d’obtenir la configuration optimale.
Lorsque vous effectuez le test, vous pouvez surveiller les compteurs de performances suivants du Agent de distribution :
- Dist : Cmds livrés/s
- Dist : Latence de remise
Comportement du Agent de distribution après avoir spécifié le paramètre SubscriptionStreams
Le Agent de distribution conserve le nombre de sessions/connexions que vous spécifiez dans SubscriptionStreams
. Le Agent de distribution utilise ces sessions pour appliquer des modifications à l’Abonné.
Toutefois, une fois que vous avez spécifié SubscriptionStreams
et que le Agent de distribution s’exécute pendant un certain temps, le Agent de distribution peut passer à l’utilisation d’une seule session pour appliquer des modifications à l’Abonné.
Raisons pour lesquelles le Agent de distribution passer à l’utilisation d’une seule session
L’Agent de distribution peut passer à l’utilisation d’une seule session pour de nombreuses raisons. Les raisons les plus courantes sont les suivantes :
Lorsque le Agent de distribution applique des modifications, l’une des sessions génère une erreur.
Par exemple, le Agent de distribution insère une ligne dans une table enfant à l’aide d’une session. Si cela se produit avant que le Agent de distribution insère la ligne correspondante dans la table parente à l’aide d’une autre session, une violation de contrainte de clé étrangère génère un message d’erreur.
Le thread de surveillance de blocage détecte le blocage. Le blocage peut se produire pour l’une des raisons suivantes :
Le Agent de distribution effectue une
INSERT
opération et uneUPDATE
opération sur une table sur l’Abonné à l’aide de différentes sessions. Si la table contient un index non cluster unique, un blocage entre les deux sessions peut se produire lorsque le Agent de distribution met à jour les clés d’index de la table.Sur l’Abonné, le Agent de distribution exécute des instructions DML (Data Manipulation Language) sur plusieurs tables. Si une vue indexée est définie sur ces tables, un blocage entre les deux sessions peut se produire lorsque la vue indexée met à jour les clés d’index partagés.
Le Agent de distribution exécute une instruction DML sur une table de l’Abonné à l’aide d’une session. Les déclencheurs DML sont définis sur cette table. Les déclencheurs DML exécutent des instructions DML sur une autre table en cours de mise à jour à l’aide d’une autre session. Dans ce cas, un blocage peut se produire entre les deux sessions.
Nous vous recommandons vivement de ne pas utiliser les objets de base de données suivants dans la base de données de l’abonné :
- Contraintes de clé étrangère
- Index non cluster uniques
- Vues indexées
- Déclencheurs DML pouvant provoquer un blocage entre les sessions
Comment déterminer si le Agent de distribution est passé à l’utilisation d’une seule session
Pour ce faire, utilisez l’une des méthodes suivantes :
Remarque
Bien que vous puissiez confirmer que le Agent de distribution n’a pas basculé vers une session à l’aide de la méthode 1, vous devez utiliser la méthode 2 ou la méthode 3 pour confirmer que le Agent de distribution est passé à l’utilisation d’une session.
Méthode 1
Interrogez la vue de gestion dynamique (DMV) sys.dm_exec_sessions pour les sessions de connexion à la base de données d’abonnement. Si vous ne voyez qu’une seule session de connexion, le Agent de distribution est peut-être passé à l’utilisation d’une seule session. Si vous voyez plusieurs sessions de connexion, le Agent de distribution utilise toujours le nombre de sessions spécifié.
Pour vérifier que le Agent de distribution a basculé vers une session, utilisez la méthode 2 ou la méthode 3.
Méthode 2
Interrogez la colonne
comments
de la table msdistribution_history dans la base de données de distribution. Si le résultat de la requête contient l’entrée suivante, le Agent de distribution est passé à l’utilisation d’une session :Le processus n’a pas réussi à terminer le dernier lot en mode multi-streaming, il a été réinitialisé en mode de connexion unique et recommencez l’opération.
Méthode 3
Examinez le fichier de sortie du Agent de distribution. Le Agent de distribution est passé à l’utilisation d’une seule session si le fichier de sortie contient le même message d’erreur que la méthode 2.
Le fichier de sortie suivant est un exemple :
Date/Time 100 transaction(s) with 1181 command(s) were delivered. Date/Time 100 transaction(s) with 2672 command(s) were delivered. Date/Time Bucket 6 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 Date/Time Bucket 1 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 Date/Time Bucket 3 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 Date/Time Bucket 0 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 Date/Time Bucket 5 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 Date/Time Bucket 2 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 Date/Time Bucket 7 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 Date/Time Bucket 4 aborted the wait for Ready To Commit event, due to thread shutdown event ... Date/Time Number of subscription streams has been reset from 8 to 1, state 4. Date/Time Disconnecting from Subscriber SQLInstance Date/Time Disconnecting from Subscriber SQLInstance Date/Time Disconnecting from Subscriber SQLInstance Date/Time Disconnecting from Subscriber SQLInstance Date/Time Disconnecting from Subscriber SQLInstance Date/Time Disconnecting from Subscriber SQLInstance Date/Time Disconnecting from Subscriber SQLInstance Date/Time Disconnecting from Subscriber SQLInstance Date/Time Connecting to Subscriber SQLInstance Date/Time The process failed to complete last batch in multi-streaming mode, it has been reset to single connection mode and is retrying the operation. Date/Time 21 transaction(s) with 390 command(s) were delivered.
Comment résoudre les problèmes d’un Agent de distribution qui passe à l’utilisation d’une seule session
Exécutez le SQL Server Profiler sur l’Abonné pour capturer l’événement de rapport de processus bloqué et l’événement Exception. Ces événements enregistrent les blocages et les erreurs qui se produisent lorsque le Agent de distribution applique des modifications.
Remarque
L’événement Exception peut être provoqué par n’importe quel type d’erreur qui peut être associé au problème. Par exemple, l’erreur peut être due à une violation de contrainte de clé étrangère.
Utilisez l’une des méthodes de la section Guide pratique pour déterminer si le Agent de distribution est passé à l’utilisation d’une seule session pour surveiller les Agent de distribution.
Si le Agent de distribution est passé à l’utilisation d’une session, arrêtez la trace.
À partir du fichier de sortie du Agent de distribution ou de la colonne
start_time
de la table msdistribution_history, obtenez l’horodatage de l’entrée suivante :Le processus n’a pas réussi à terminer le dernier lot en mode multi-streaming, il a été réinitialisé en mode de connexion unique et recommencez l’opération.
Ouvrez le fichier de trace (.trc) à partir de l’Abonné. Recherchez un script bloquant ou un événement d’exception dont l’horodatage est identique ou très proche de l’horodatage que vous avez obtenu à l’étape 4.
Si vous remarquez une exception, examinez les détails de l’exception pour en déterminer la cause. Par exemple, l’exception peut être provoquée par une violation de contrainte de clé étrangère. Si c’est le cas, nous vous recommandons de supprimer la contrainte de clé étrangère dans la base de données de l’Abonné.
Si vous remarquez un script bloquant, le problème est dû au blocage. Voici un exemple de script bloquant :
<blocked-process-report monitorLoop="41589"> <blocked-process> <process id="process3a6d438" taskpriority="0" logused="24592" waitresource="KEY: 6:72057594375700480 (0100e420fa5a)" waittime="9937" ownerId="568644832" transactionname="user_transaction" lasttranstarted="2008-05-05T04:55:04.430" XDES="0xa5619e370" lockMode="X" schedulerid="11" kpid="6104" status="suspended" spid="58" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2008-05-05T04:55:04.553" lastbatchcompleted="2008-05-05T04:55:04.430" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct> isolationlevel="read committed (2)" xactid="568644832" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056"> <executionStack> <frame line="5" stmtstart="642" stmtend="1600" sqlhandle="0x0300060057a14477a8c6dd00609a00000100000000000000"/> </executionStack> <inputbuf> Proc [Database Id = 6 Object Id = 2000986455] </inputbuf> </process> </blocked-process> <blocking-process> <process status="sleeping" spid="68" sbid="0" ecid="0" priority="0" transcount="1" lastbatchstarted="2008-05-05T04:55:04.570" lastbatchcompleted="2008-05-05T04:55:05.103" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct> isolationlevel="read committed (2)" xactid="568644998" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056"> <executionStack/> <inputbuf> Proc [Database Id = 6 Object Id = 1172459501] </inputbuf> </process> </blocking-process> </blocked-process-report>
Le script de blocage enregistre une session bloquée et une session bloquante. La session bloquée démarre à partir de la balise
<blocked-process>
. La session de blocage démarre à partir de la balise<blocking-process>
.Recherchez le
Object Id
de l’objetProc
dans la session bloquée et dans la session bloquante.Dans l’exemple de script de blocage, le
Object Id
deProc
dans la session bloquée est2000986455
. LeObject Id
deProc
dans la session de blocage est1172459501
.Dans la base de données d’abonnement, interrogez la vue sys.objects en spécifiant que la colonne
object_id
doit être égale aux ID d’objet que vous avez obtenus à l’étape 7. Dans ce cas, vous pouvez déterminer les noms d’objets.Par exemple, exécutez la requête suivante dans le contexte de la base de données d’abonnement :
USE <SubDBName> GO SELECT name FROM sys.objects WHERE object_id = 1172459501 OR object_id = 2000986455
Remarque
- L’espace réservé
<SubDBName>
représente le nom de la base de données d’abonnement. - En règle générale, ces objets sont des procédures stockées utilisées dans la réplication.
- L’espace réservé
Déterminez l’index ou la vue indexée qui provoque le blocage. Pour cela, procédez comme suit :
Dans le script de blocage, recherchez la valeur de la propriété
waitresource
.Dans l’exemple de script de blocage, la valeur de
waitresource
est72057594375700480
.Interrogez la vue sys.partitions pour obtenir l’ID d’objet et l’ID d’index en spécifiant que la colonne
PARTITION_ID
doit être égale à la valeur du que vous avez obtenue à l’étapewaitresource
9a.Par exemple, exécutez la requête suivante :
SELECT object_id, index_id FROM SYS.PARTITIONS WHERE PARTITION_ID=72057594375700480
Dans la base de données d’abonnement, interrogez la vue sys.indexes pour déterminer l’index à l’aide de l’ID d’objet et de l’ID d’index que vous avez obtenus à l’étape 9b.
Par exemple, exécutez la requête suivante :
USE <SubDBName> GO SELECT name, type_desc, is_unique FROM sys.indexes WHERE object_id = <objID> and index_id = <idxID>
Remarque
- L’espace réservé
<objID>
représente l’ID d’objet que vous avez obtenu à l’étape 9b. - L’espace réservé
<idxID>
représente l’ID d’index que vous avez obtenu à l’étape 9b.
- L’espace réservé
Si le blocage est dû à une vue indexée, nous vous recommandons de supprimer la vue indexée. Si le blocage est dû à un index non cluster unique, nous vous recommandons de supprimer l’index, puis de recréer un index non unique.
Description du thread de surveillance de blocage
Le Agent de distribution gère un thread de surveillance de blocage qui détecte le blocage entre les sessions. Si le thread du moniteur de blocage détecte un blocage entre les sessions, le Agent de distribution passe à l’utilisation d’une session pour réappliquer le lot actuel de commandes que le Agent de distribution n’a pas pu appliquer précédemment.
Pour plus d’informations sur le thread de surveillance de blocage, consultez Thread de moniteur de blocage.
Comment le Agent de distribution reprend plusieurs sessions
Avant que le Agent de distribution puisse reprendre plusieurs sessions, le Agent de distribution doit exécuter la procédure sp_MSget_repl_commands
stockée pour demander à nouveau la base de données de distribution pour les commandes qui n’ont pas été appliquées sur l’Abonné. Ensuite, le Agent de distribution doit appliquer toutes ces commandes sur l’Abonné avant que le Agent de distribution puisse reprendre plusieurs sessions. Dans un environnement de réplication latente, le Agent de distribution ne peut pas reprendre plusieurs sessions, car le Agent de distribution doit appliquer de nombreuses commandes sur l’Abonné avant que le Agent de distribution puisse reprendre plusieurs sessions.
Pour suivre l’ensemble du processus, examinez le fichier de sortie du Agent de distribution.
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour