Freigeben über


Konfigurieren und Problembehandlung des SubscriptionStreams-Parameters des Verteilungs-Agent in SQL Server

Ursprüngliche Produktversion: SQL Server (alle unterstützten Versionen)
Ursprüngliche KB-Nummer: 953199

Dieser Artikel enthält weitere Informationen zu dem Parameter, bewährten Methoden bei der Verwendung dieses Parameters SubscriptionStreamsund der zugehörigen Problembehandlung.

Einführung

Der Parameter SubscriptionStreams kann verwendet werden, um die Anzahl der Verbindungen zu steuern. In einer Transaktionsreplikation in Microsoft SQL Server können Sie den Parameter verwenden, um mehrere Verbindungen zu aktivieren, die vom Verteilungs-Agent zum Anwenden von Batches von Änderungen parallel zu einem Abonnenten verwendet werden. Dieser Vorgang verbessert den Replikationsdurchsatz erheblich. Gleichzeitig kann die Verteilungs-Agent weiterhin viele der gleichen Transaktionsmerkmale beibehalten, als wenn die Verteilungs-Agent eine einzige Verbindung verwendet, um die Änderungen anzuwenden. Wenn eine der Verbindungen oder ein Commit hierfür nicht ausgeführt werden kann, wird der aktuelle Batch von allen Verbindungen verworfen, und der Agent versucht mithilfe eines einzigen Datenstroms, die fehlgeschlagenen Batches zu wiederholen. Vor dem Abschluss dieser Wiederholungsphase kann es auf dem Abonnenten vorübergehend zur Transaktionsinkonsistenzen kommen. Nach dem erfolgreichen Ausführen (Commit) der fehlgeschlagenen Batches wird der Abonnent wieder in einen Zustand der Transaktionskonsistenz versetzt.

Wenn Sie einen Wert von 2 oder höher für den Parameter SubscriptionStreamsangeben, kann die Reihenfolge, in der Transaktionen beim Abonnenten empfangen werden, von der Reihenfolge abweichen, in der sie beim Herausgeber getätigt wurden. Wenn dieses Verhalten Einschränkungen während der Synchronisierung verursacht, sollten Sie die NOT FOR REPLICATION Option verwenden, um die Erzwingung von Einschränkungen während der Synchronisierung zu deaktivieren. Weitere Informationen finden Sie unter Steuern des Verhaltens von Triggern und Einschränkungen in der Synchronisierung.

Zu berücksichtigende Faktoren vor dem Aktivieren von SubscriptionStreams

SubscriptionStreams kümmert sich hauptsächlich um latenz von Distributor zu Subscriber, also bevor Sie sich entscheiden SubscriptionStreams, dafür zu gehen, stellen Sie sicher, dass Sie tatsächlich latenz von Distributor zu Subscriber laufen. Sie können Ablaufverfolgungstoken entweder im Replikationsmonitor oder Leistungsmonitor Indikatoren wie SQLServer:Replication Dist verwenden.>Dist:Delivery Latency to have a idea of the level of latency.

Latenz von Distributor zu Subscriber kann aus vielen Gründen verursacht werden, wie z. B. die folgenden:

  • Blockieren entweder bei Distributor oder Abonnent
  • Jeder Engpass, entweder bei Distributor oder Abonnent, z. B. langsame Festplattenlaufwerke, langsame Netzwerkbandbreite und veraltete Statistiken
  • Massentransaktionen, die von Publisher stammen
  • Die Rate der eingehenden Transaktionen von Publisher ist zu hoch.
  • Trigger oder unnötige Indizes in der abonnierten Datenbank

Der Datenbankadministrator (DBA) muss einen Anruf ausführen und testen, ob SubscriptionStreams er ihnen helfen soll oder nicht. Wenn sie z. B. bei der Blockierung bei Subscriber blockiert werden, hilft das Erhöhen der Anzahl gleichzeitiger Verbindungen nicht, kann aber die Situation noch schlimmer machen. Während in Situationen wie der eingehende Transaktionssatz von Publisher zu hoch ist und Sie das Gefühl haben, dass ein einzelner Thread für die Verteilungs-Agent die eingehende Last nicht bewältigen kann, können Sie den Wert des Parameters SubscriptionStreams auf >=2 erhöhen. Es kann auch bei langsamen Netzwerk- und Langsamdatenträgersituationen hilfreich sein. Im Idealfall ist der maximale Wert für diesen Parameter 64, aber der empfohlene Wert (oder ein guter Wert für den Anfang) entspricht der Anzahl der physischen Prozessoren am Ziel (Abonnent).

Konfigurieren des Parameters "SubscriptionStreams"

SubscriptionStreamsist einer dieser Parameter, der in Verteilungs-Agent Profil im Replikationsmonitor nicht sichtbar ist. Sie können einen Wert für diesen Agent-Parameter mithilfe @subscriptionstreams von sp_addsubscription (Transact-SQL) angeben oder diesen Parameter dem Befehlsabschnitt des Verteilungs-Agent-Auftragsbefehls hinzufügen, indem Sie das folgende Verfahren verwenden:

  1. Öffnen Sie den Replikationsmonitor, erweitern Sie "Mein Herausgeber", und wählen Sie ihre Publikation im linken Fenster aus. Im rechten Bereichsfenster wird unter dem Abschnitt "Alle Abonnements " die Liste aller Abonnenten dieser Publikation angezeigt.

  2. Klicken Sie mit der rechten Maustaste auf den Abonnenten, den Sie aktivieren SubscriptionStreams möchten, und wählen Sie "Details anzeigen" aus. Ein neues Fenster wird mit den Verteilungs-Agent Sitzungsdetails angezeigt.

  3. Wählen Sie in diesem neuen Fenster oben in der Menüleiste "Aktion" aus, und wählen Sie Verteilungs-Agent Auftragseigenschaften aus. Dadurch wird das Fenster "Auftragseigenschaften" für die Verteilungs-Agent geöffnet.

  4. Wählen Sie im linken Fenster "Schritte " und dann "Agent ausführen" im rechten Fenster aus, und wählen Sie dann "Bearbeiten" aus. Ein neues Fenster wird eingeblendt.

  5. Scrollen Sie zum Ende des Befehlsabschnitts (ganz rechts), und fügen Sie diesen Parameter -SubscriptionStreams 6 an.

  6. Speichern Sie die Einstellungen, und starten Sie den Verteilungs-Agent Auftrag neu. Für die Implementierung der Änderungen ist ein Neustart von Verteilungs-Agent erforderlich.

Notiz

Im obigen Beispiel ist die Festlegung auf 6, was bedeutet, SubscriptionStreams dass wir nach sechs parallelen Verbindungen für Verteilungs-Agent beim Abonnenten suchen. Sie können diese Zahl gemäß Ihrer Umgebung und Tests festlegen.

Ermitteln der Anzahl der Datenströme

Möglicherweise bemerken Sie Leistungsverbesserungen mithilfe des Parameters SubscriptionStreams. Wenn es eine Verbesserung gibt, kann die Verbesserung nominal sein. Es ist schwierig zu bestimmen, welche Art von Leistungsverbesserung jedes Datenträgersubsystem auf dem Markt durch die Verwendung SubscriptionStreamsbietet. Daher wird empfohlen, eine Testumgebung vorzubereiten, die die Produktionsumgebung simuliert. Sie können Szenarien testen, die SubscriptionStreams mithilfe verschiedener Konfigurationswerte und eines Szenarios verwendet werden, das nicht verwendet SubscriptionStreamswird.

Es wird empfohlen, Dass Sie Auslastungstests für die Publikation und das Abonnement durchführen, um die Leistungsverbesserungen zu ermitteln, die Sie mithilfe von SubscriptionStreams. Sie sollten die Leistungsbasisplantests durchführen, um den erwarteten Durchsatz des Datenträgersubsystems zu verstehen. Bevor Sie jeden Test durchführen, wenden Sie viele Änderungen an, um eine Last im Publisher zu erstellen. Stellen Sie beim Erstellen der Last sicher, dass Verteilungs-Agent nicht ausgeführt wird. Wenn die Replikation über ausreichende Latenz verfügt, führen Sie die Verteilungs-Agent aus, um die Leistung für die folgenden Konfigurationen zu testen:

  • Verwenden Sie den Parameter SubscriptionStreamsnicht.
  • Legen Sie den Wert SubscriptionStreams fest, der der Anzahl der Prozessoren auf dem Server entspricht. Wenn der Server beispielsweise acht Prozessoren aufweist, legen Sie den Wert von SubscriptionStreams 8 fest.
  • Geben Sie unterschiedliche Werte an SubscriptionStreams , um die optimale Konfiguration zu erhalten.

Wenn Sie den Test durchführen, können Sie die folgenden Leistungsindikatoren der Verteilungs-Agent überwachen:

  • Dist: Gelieferte Cmds/Sek.
  • Dist: Übermittlungslatenz

Verhalten der Verteilungs-Agent nach dem Angeben des Parameters "SubscriptionStreams"

Die Verteilungs-Agent verwaltet die Anzahl der Sitzungen/Verbindungen, in SubscriptionStreamsdenen Sie angeben. Die Verteilungs-Agent verwendet diese Sitzungen, um Änderungen am Abonnenten anzuwenden.

Nachdem Sie jedoch angegeben SubscriptionStreams und die Verteilungs-Agent einige Zeit ausgeführt wurde, kann die Verteilungs-Agent zur Verwendung nur einer Sitzung wechseln, um Änderungen auf den Abonnenten anzuwenden.

Gründe für die Verteilungs-Agent, nur eine Sitzung zu verwenden

Die Verteilungs-Agent kann aus vielen Gründen nur eine Sitzung verwenden. Im Folgenden sind die häufigsten Gründe aufgeführt:

  • Wenn die Verteilungs-Agent Änderungen anwendet, löst eine der Sitzungen einen Fehler aus.

    Beispielsweise fügt die Verteilungs-Agent eine Zeile mithilfe einer Sitzung in eine untergeordnete Tabelle ein. Wenn dies geschieht, bevor die Verteilungs-Agent die entsprechende Zeile mithilfe einer anderen Sitzung in die übergeordnete Tabelle einfügt, löst eine Verletzung der Fremdschlüsseleinschränkung eine Fehlermeldung aus.

  • Der blockierende Monitorthread erkennt die Blockierung. Das Blockieren kann aus einem der folgenden Gründe auftreten:

    • Die Verteilungs-Agent führt eine INSERT und einen UPDATE Vorgang in einer Tabelle am Abonnenten mithilfe verschiedener Sitzungen aus. Wenn die Tabelle einen eindeutigen nicht gruppierten Index enthält, kann die Blockierung zwischen den beiden Sitzungen auftreten, wenn die Verteilungs-Agent die Indexschlüssel der Tabelle aktualisiert.

    • Beim Abonnenten führt die Verteilungs-Agent Datenmanipulationssprache (Data Manipulation Language, DML)-Anweisungen für mehrere Tabellen aus. Wenn eine indizierte Ansicht für diese Tabellen definiert ist, kann die Blockierung zwischen den beiden Sitzungen auftreten, wenn die indizierte Ansicht die freigegebenen Indexschlüssel aktualisiert.

    • Die Verteilungs-Agent führt eine DML-Anweisung für eine Tabelle am Abonnenten mithilfe einer Sitzung aus. DML-Trigger werden in dieser Tabelle definiert. Die DML-Trigger führen DML-Anweisungen für eine andere Tabelle aus, die mithilfe einer anderen Sitzung aktualisiert wird. In diesem Fall kann die Blockierung zwischen den beiden Sitzungen auftreten.

Es wird dringend empfohlen, die folgenden Datenbankobjekte in der Abonnentendatenbank nicht zu verwenden:

  • Fremdschlüsseleinschränkungen
  • Eindeutige nicht gruppierte Indizes
  • Indizierte Sichten
  • DML-Trigger, die das Blockieren zwischen Sitzungen verursachen können

Ermitteln, ob der Verteilungs-Agent nur eine Sitzung verwendet hat

Wenden Sie hierzu eine der folgenden Methoden an:

Notiz

Sie können zwar bestätigen, dass die Verteilungs-Agent nicht mithilfe der Methode 1 zu einer Sitzung gewechselt hat, sie müssen jedoch die Methode 2 oder Methode 3 verwenden, um zu bestätigen, dass die Verteilungs-Agent zu einer Sitzung gewechselt wurde.

  • Methode 1

    Abfragen der dynamischen Verwaltungsansicht (Dynamic Management View, DMV) sys.dm_exec_sessions für die Verbindungssitzungen mit der Abonnementdatenbank. Wenn nur eine Verbindungssitzung angezeigt wird, hat die Verteilungs-Agent möglicherweise zu einer Sitzung gewechselt. Wenn mehr als eine Verbindungssitzung angezeigt wird, verwendet die Verteilungs-Agent weiterhin die angegebene Anzahl von Sitzungen.

    Um zu bestätigen, dass die Verteilungs-Agent zu einer Sitzung gewechselt wurde, verwenden Sie Methode 2 oder Methode 3.

  • Methode 2

    Abfragen der Spalte comments der Tabelle msdistribution_history in der Verteilungsdatenbank. Wenn das Ergebnis der Abfrage den folgenden Eintrag enthält, hat der Verteilungs-Agent zu einer Sitzung gewechselt:

    Der Prozess konnte den letzten Batch im Multistreamingmodus nicht abschließen, es wurde auf den einzelverbindungsmodus zurückgesetzt und versucht den Vorgang erneut.

  • Methode 3

    Überprüfen Sie die Ausgabedatei des Verteilungs-Agent. Die Verteilungs-Agent wurde nur zu einer Sitzung gewechselt, wenn die Ausgabedatei dieselbe Fehlermeldung wie Methode 2 enthält.

    Die folgende Ausgabedatei ist ein Beispiel:

    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.
    

Problembehandlung für eine Verteilungs-Agent, die nur eine Sitzung verwendet

  1. Führen Sie den SQL Server Profiler beim Abonnenten aus, um das Ereignis "Blockierter Prozessbericht" und das Ausnahmeereignis zu erfassen. Diese Ereignisse zeichnen Blockierung und Fehler auf, die auftreten, wenn die Verteilungs-Agent Änderungen anwendet.

    Notiz

    Das Ausnahmeereignis kann durch jede Art von Fehler verursacht werden, die mit dem Problem verbunden sein können. Der Fehler kann beispielsweise durch einen Fremdschlüsseleinschränkungsverstoß verursacht werden.

  2. Verwenden Sie eine der Methoden im How to determine whether the Verteilungs-Agent has switched to using only one session section to monitor the Verteilungs-Agent.

  3. Wenn die Verteilungs-Agent zu einer Sitzung gewechselt ist, beenden Sie die Ablaufverfolgung.

  4. Rufen Sie aus der Ausgabedatei der Verteilungs-Agent oder aus der Spalte start_time der Tabelle msdistribution_history den Zeitstempel des folgenden Eintrags ab:

    Der Prozess konnte den letzten Batch im Multistreamingmodus nicht abschließen, es wurde auf den einzelverbindungsmodus zurückgesetzt und versucht den Vorgang erneut.

  5. Öffnen Sie die Ablaufverfolgungsdatei (TRC) aus dem Abonnenten. Suchen Sie ein blockierende Skript oder ein Ausnahmeereignis, dessen Zeitstempel mit dem in Schritt 4 abgerufenen Zeitstempel identisch oder sehr nahe am Zeitstempel ist.

  6. Wenn Sie eine Ausnahme bemerken, untersuchen Sie die Details der Ausnahme, um die Ursache zu ermitteln. Die Ausnahme kann beispielsweise durch eine Verletzung der Fremdschlüsseleinschränkung verursacht werden. In diesem Falls wird empfohlen, die Fremdschlüsseleinschränkung in der Abonnentendatenbank zu entfernen.

    Wenn Sie ein blockierende Skript bemerken, wird das Problem durch Blockieren verursacht. Es folgt ein Beispiel für ein Blockierungsskript:

    <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> 
    

    Das blockierende Skript zeichnet eine blockierte Sitzung und eine Blockierungssitzung auf. Die blockierte Sitzung beginnt mit dem Tag <blocked-process>. Die Blockierungssitzung beginnt mit dem Tag <blocking-process>.

  7. Suchen Sie das Object Id Objekt Proc in der blockierten Sitzung und in der Blockierungssitzung.

    Im Beispielblockierungsskript ist 2000986455die Proc Object Id in der blockierten Sitzung . Die Object Id in Proc der Blockierungssitzung ist 1172459501.

  8. Fragen Sie in der Abonnementdatenbank die Ansicht sys.objects ab, indem Sie die Spalte object_id angeben, die den in Schritt 7 abgerufenen Objekt-IDs entspricht. In diesem Fall können Sie die Objektnamen bestimmen.

    Führen Sie beispielsweise die folgende Abfrage im Kontext der Abonnementdatenbank aus:

    USE <SubDBName> 
    GO 
    SELECT name FROM sys.objects 
    WHERE object_id = 1172459501 OR object_id = 2000986455 
    

    Notiz

    • Der Platzhalter <SubDBName> stellt den Namen der Abonnementdatenbank dar.
    • In der Regel sind diese Objekte gespeicherte Prozeduren, die in der Replikation verwendet werden.
  9. Bestimmen Sie den Index oder die indizierte Ansicht, die eine Blockierung verursacht. Gehen Sie dazu wie folgt vor:

    1. Suchen Sie im Blockierungsskript den Wert der Eigenschaft waitresource.

      Im Beispielblockierungsskript ist 72057594375700480der Wert von waitresource .

    2. Fragen Sie die Ansicht sys.partitions ab, um die Objekt-ID und die Index-ID abzurufen, indem Sie die Spalte PARTITION_ID angeben, die dem Wert des waitresource in Schritt 9a abgerufenen Werts entspricht.

      Führen Sie beispielsweise die folgende Abfrage aus:

      SELECT object_id, index_id FROM SYS.PARTITIONS WHERE PARTITION_ID=72057594375700480
      
    3. Fragen Sie in der Abonnementdatenbank die Ansicht sys.indexes ab, um den Index mithilfe der Objekt-ID und der Index-ID zu ermitteln, die Sie in Schritt 9b abgerufen haben.

      Führen Sie beispielsweise die folgende Abfrage aus:

      USE <SubDBName> 
      GO 
      SELECT name, type_desc, is_unique FROM sys.indexes 
      WHERE object_id = <objID> and index_id = <idxID>
      

      Notiz

      • Der Platzhalter <objID> stellt die Objekt-ID dar, die Sie in Schritt 9b abgerufen haben.
      • Der Platzhalter <idxID> stellt die Index-ID dar, die Sie in Schritt 9b abgerufen haben.
  10. Wenn die Blockierung durch eine indizierte Ansicht verursacht wird, wird empfohlen, die indizierte Ansicht abzulegen. Wenn das Blockieren durch einen eindeutigen nicht gruppierten Index verursacht wird, empfehlen wir, den Index abzulegen und dann einen nicht eindeutigen Index neu zu erstellen.

Beschreibung des blockierenden Monitorthreads

Der Verteilungs-Agent verwaltet einen blockierenden Monitorthread, der das Blockieren zwischen den Sitzungen erkennt. Wenn der blockierende Monitorthread die Blockierung zwischen den Sitzungen erkennt, wechselt die Verteilungs-Agent zur Verwendung einer Sitzung, um den aktuellen Batch von Befehlen erneut anzuwenden, die der Verteilungs-Agent zuvor nicht anwenden konnte.

Weitere Informationen zum blockierenden Monitorthread können Sie im Blockierungs-Monitorthread überprüfen.

Fortsetzen mehrerer Sitzungen durch die Verteilungs-Agent

Bevor die Verteilungs-Agent mehrere Sitzungen fortsetzen kann, muss die Verteilungs-Agent die gespeicherte Prozedur sp_MSget_repl_commands ausführen, um die Verteilungsdatenbank für die Befehle erneut abzufragn, die nicht auf den Abonnenten angewendet wurden. Anschließend muss der Verteilungs-Agent alle diese Befehle beim Abonnenten anwenden, bevor die Verteilungs-Agent mehrere Sitzungen fortsetzen kann. In einer latenten Replikationsumgebung kann der Verteilungs-Agent nicht mehrere Sitzungen fortsetzen, da die Verteilungs-Agent viele Befehle am Abonnenten anwenden muss, bevor die Verteilungs-Agent mehrere Sitzungen fortsetzen kann.

Überprüfen Sie die Ausgabedatei des Verteilungs-Agent, um den gesamten Prozess nachzuverfolgen.