Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Probleme bei der SQL Server-Transaktionsreplikation

Wir haben bereits früher über Probleme mit der SQL Server-Transaktionsreplikation gesprochen. Jetzt werden wir mit einigen weiteren praktischen Demos fortfahren, um häufig auftretende Leistungsprobleme bei der Replikation zu verstehen und sie richtig zu beheben.

Wir haben bereits Probleme wie Konfigurationsprobleme, Berechtigungsprobleme, Konnektivitätsprobleme und Datenintegritätsprobleme sowie deren Fehlerbehebung und Behebung besprochen. Jetzt konzentrieren wir uns auf verschiedene Leistungsprobleme und Korruptionsprobleme, die sich auf die SQL Server-Replikation auswirken.

Da Korruptionsprobleme ein großes Thema sind, werden wir ihre Auswirkungen nur in diesem Artikel diskutieren und nicht ins Detail gehen. Ich habe mehrere Szenarien ausgewählt, die aufgrund meiner Erfahrung unter Leistungs- und Korruptionsprobleme fallen können:

  • Leistungsprobleme
    • Aktive Transaktionen mit langer Laufzeit in der Publisher-Datenbank
    • Massen-INSERT/UPDATE/DELETE-Operationen für Artikel
    • Riesige Datenänderungen innerhalb einer einzigen Transaktion
    • Sperrungen in der Verteilungsdatenbank
  • Korruptionsbezogene Probleme
    • Beschädigungen der Publisher-Datenbank
    • Beschädigungen der Verteilungsdatenbank
    • Beschädigungen der Abonnentendatenbank
    • MSDB-Datenbankbeschädigungen

Leistungsprobleme

Die SQL Server-Transaktionsreplikation ist eine komplizierte Architektur, die mehrere Parameter wie die Herausgeberdatenbank, die Verteiler-(Verteilungs-)Datenbank, die Abonnentendatenbank und mehrere Replikations-Agents umfasst, die als SQL Server-Agent-Jobs ausgeführt werden.

Da wir alle diese Elemente in unseren vorherigen Artikeln ausführlich besprochen haben, kennen wir die Bedeutung jedes einzelnen für die Replikationsfunktion. Alles, was sich auf diese Komponenten auswirkt, kann die SQL Server-Replikationsleistung beeinträchtigen.

Beispielsweise enthält die Publisher-Datenbankinstanz eine kritische Datenbank mit vielen Transaktionen pro Sekunde. Die Serverressourcen haben jedoch einen Engpass wie die konsistente CPU-Auslastung über 90 % oder die Speicherauslastung über 90 %. Dies wirkt sich definitiv auf die Leistung des Protokollleseagentenjobs aus, der die Änderungsdaten aus Transaktionsprotokollen der Herausgeberdatenbank liest.

In ähnlicher Weise können sich solche Szenarien über Verteiler- oder Abonnentendatenbankinstanzen hinweg auf den Snapshot-Agent oder den Verteilungs-Agent auswirken. Als DBA müssen Sie also sicherstellen, dass die Serverressourcen wie CPU, physischer Speicher und Netzwerkbandbreite für die Datenbankinstanzen des Herausgebers, Verteilers und Abonnenten effizient konfiguriert sind.

Unter der Annahme, dass die Herausgeber-, Abonnenten- und Verteiler-Datenbankserver richtig konfiguriert sind, können die Replikationsleistungsprobleme immer noch auftreten, wenn die folgenden Szenarien auftreten.

Lange laufende aktive Transaktionen in der Publisher-Datenbank

Wie der Name schon sagt, zeigen Long-Running Active Transactions an, dass ein Anwendungsaufruf oder eine Benutzeroperation innerhalb des Transaktionsbereichs für lange Zeit ausgeführt wird.

Das Finden einer aktiven Transaktion mit langer Laufzeit bedeutet, dass die Transaktion noch nicht festgeschrieben ist und von der Anwendung entweder zurückgesetzt oder festgeschrieben werden kann. Dadurch wird verhindert, dass das Transaktionsprotokoll abgeschnitten wird, was dazu führt, dass die Dateigröße des Transaktionsprotokolls kontinuierlich zunimmt.

Der Protokolllese-Agent sucht nach allen festgeschriebenen Datensätzen, die für die Replikation aus Transaktionsprotokollen in einer serialisierten Reihenfolge basierend auf der Protokollsequenznummer (LSN) markiert sind, und überspringt alle anderen Änderungen, die für nicht replizierte Artikel vorgenommen werden. Wenn die lang laufenden aktiven Transaktionsbefehle noch nicht festgeschrieben sind, überspringt die Replikation das Senden dieser Befehle und sendet alle anderen festgeschriebenen Transaktionen an die Verteilungsdatenbank. Sobald die lang laufende aktive Transaktion festgeschrieben ist, werden Datensätze an die Verteilungsdatenbank gesendet, und bis zu diesem Zeitpunkt wird der inaktive Teil der Transaktionsprotokolldatei der Herausgeber-DB nicht gelöscht, wodurch die Größe der Transaktionsprotokolldatei der Herausgeber-Datenbank zunimmt.

Wir können das Szenario „Long-Running Active Transaction“ testen, indem wir die folgenden Schritte ausführen:

Standardmäßig bereinigt der Verteilungs-Agent alle festgeschriebenen Änderungen in der Abonnentendatenbank und behält den letzten Datensatz bei, um die neuen Änderungen basierend auf der Protokollfolgenummer (LSN) zu überwachen.

Wir können die folgenden Abfragen ausführen, um den Status der in MSRepl_Commands verfügbaren Datensätze zu überprüfen Tabellen oder mit sp_browsereplcmds Prozedur in der Distributionsdatenbank:

exec sp_browsereplcmds
GO
SELECT * FROM MSrepl_commands

Öffnen Sie nun ein neues Abfragefenster und führen Sie das folgende Skript aus, um eine lang andauernde aktive Transaktion auf AdventureWorks zu erstellen Datenbank. Beachten Sie, dass das folgende Skript keine ROLLBACK- oder COMMIT TRANSACTION-Befehle enthält. Daher raten wir davon ab, diese Art von Befehlen in der Produktionsdatenbank auszuführen.

BEGIN TRANSACTION 

SET IDENTITY_INSERT Person.ContactType ON;
insert into person.ContactType (ContactTypeId, Name, ModifiedDate) values ( 22, 'Test New Position', GETDATE());
SET IDENTITY_INSERT Person.ContactType OFF;

Wir können überprüfen, ob dieser neue Datensatz nicht in die Abonnentendatenbank repliziert wurde. Dazu führen wir die SELECT-Anweisung für Person.ContactType aus Tabelle in der Abonnentendatenbank:

Lassen Sie uns überprüfen, ob der obige INSERT-Befehl vom Protokollleseagenten gelesen und in die Verteilungsdatenbank geschrieben wurde.

Führen Sie die Skripte aus dem Teil von Schritt 1 erneut aus. Die Ergebnisse zeigen immer noch denselben alten Status und bestätigen, dass der Datensatz nicht aus den Transaktionsprotokollen der Publisher-Datenbank gelesen wurde.

Öffnen Sie nun eine Neue Abfrage Fenster und führen Sie das folgende UPDATE-Skript aus, um zu sehen, ob der Protokollleseagent die lange laufende aktive Transaktion überspringen und die Änderungen lesen konnte, die von dieser UPDATE-Anweisung vorgenommen wurden.

UPDATE AdventureWorks.dbo.AWBuildVersion
SET ModifiedDate  = GETDATE()

Überprüfen Sie die Verteilungsdatenbank, ob der Protokollleseagent diese Änderung erfassen konnte. Führen Sie das Skript als Teil von Schritt 1 aus:

Da die obige UPDATE-Anweisung in der Verlegerdatenbank festgeschrieben wurde, konnte der Protokollleseagent diese Änderung scannen und in die Verteilungsdatenbank einfügen. Anschließend wurde diese Änderung wie unten gezeigt auf die Abonnentendatenbank angewendet:

INSERT auf Person.ContactType wird erst in die Abonnentendatenbank repliziert, nachdem die INSERT-Transaktion in der Verlegerdatenbank festgeschrieben wurde. Bevor wir uns verpflichten, können wir schnell prüfen, wie wir eine lang andauernde aktive Transaktion identifizieren, verstehen und effizient handhaben können.

Identifizieren Sie eine lang andauernde aktive Transaktion

Öffnen Sie ein neues Abfragefenster, um nach lang andauernden aktiven Transaktionen in einer beliebigen Datenbank zu suchen und verbinden Sie sich mit der jeweiligen Datenbank, die wir überprüfen müssen. Führen Sie DBCC OPENTRAN aus Konsolenbefehl – ​​Dies ist ein Datenbankkonsolenbefehl zum Anzeigen der Transaktionen, die zum Zeitpunkt der Ausführung in der Datenbank geöffnet sind.

USE AdventureWorks
GO
DBCC OPENTRAN

Jetzt wissen wir, dass es eine SPID gab (Serverprozess-ID ) 69 lange laufen. Lassen Sie uns mithilfe von DBCC INPUTBUFFER überprüfen, welcher Befehl für diese Transaktion ausgeführt wurde console-Befehl (ein Datenbankkonsolenbefehl, der verwendet wird, um den Befehl oder Vorgang zu identifizieren, der auf der ausgewählten Serverprozess-ID ausgeführt wird).

Zur besseren Lesbarkeit kopiere ich die EventInfo Feldwert und formatieren Sie ihn so, dass er den zuvor ausgeführten Befehl anzeigt.

Wenn es in der ausgewählten Datenbank keine lang andauernden aktiven Transaktionen gibt, erhalten wir die folgende Meldung:

Ähnlich dem DBCC OPENTRAN Konsolenbefehl können wir SELECT von DMV namens sys.dm_tran_database_transactions um detailliertere Ergebnisse zu erhalten (weitere Daten finden Sie im MSDN-Artikel).

Jetzt wissen wir, wie wir die lang andauernde Transaktion identifizieren können. Wir können die Transaktion festschreiben und sehen, wie die INSERT-Anweisung repliziert wird.

Gehen Sie zu dem Fenster, in dem wir den Datensatz zu Person.ContactType eingefügt haben Tabelle innerhalb des Transaktionsbereichs und führen Sie COMMIT TRANSACTION wie unten gezeigt aus:

Durch die Ausführung von COMMIT TRANSACTION wurde der Datensatz in der Herausgeberdatenbank festgeschrieben. Daher sollte es in der Verteilungsdatenbank und der Abonnentendatenbank sichtbar sein:

Wie Sie bemerkt haben, wurden die älteren Datensätze aus der Verteilungsdatenbank durch den Bereinigungsauftrag des Verteilungs-Agents bereinigt. Der neue Datensatz für INSERT auf Person.ContactType Tabelle war in MSRepl_cmds sichtbar Tabelle.

Aus unseren Tests haben wir die folgenden Dinge gelernt:

  • Der Auftrag des Protokolllese-Agents der SQL Server-Transaktionsreplikation scannt nur aus den Transaktionsprotokollen der Herausgeberdatenbank und INSERT in die Abonnentendatenbank nach festgeschriebenen Datensätzen.
  • Die Reihenfolge geänderter Daten in der Publisher-Datenbank, die an den Abonnenten gesendet werden, basiert auf dem Committed-Status und der Zeit in der Publisher-Datenbank, auch wenn die replizierten Daten die gleiche Zeit wie die Publisher-Datenbank haben.
  • Das Identifizieren lang andauernder aktiver Transaktionen kann dabei helfen, das Wachstum von Transaktionsprotokolldateien von Herausgebern, Verteilern oder Abonnenten oder anderen Datenbanken zu beheben.

Bulk-SQL-INSERT/UPDATE/DELETE-Operationen für Artikel

Bei riesigen Datenmengen, die sich in der Publisher-Datenbank befinden, müssen wir häufig riesige Datensätze in replizierten Tabellen EINFÜGEN, AKTUALISIEREN oder LÖSCHEN.

Wenn die INSERT-, UPDATE- oder DELETE-Operationen in einer einzigen Transaktion ausgeführt werden, bleibt die Replikation definitiv lange hängen.

Nehmen wir an, wir müssen 10 Millionen Datensätze in eine replizierte Tabelle einfügen. Das Einfügen dieser Datensätze in einem einzigen Schuss führt zu Leistungsproblemen.

INSERT INTO REplicated_table
SELECT * FROM Source_table

Stattdessen können wir Datensätze in Stapeln von 0,1 oder 0,5 Millionen Datensätzen in einem WHILE einfügen Schleife oder CURSOR-Schleife , und es sorgt für eine schnellere Replikation. Wir erhalten möglicherweise keine größeren Probleme für INSERT-Anweisungen, es sei denn, die betroffene Tabelle hat viele Indizes. Dies hat jedoch einen großen Leistungseinbruch für die UPDATE- oder DELETE-Anweisungen zur Folge.

Angenommen, wir haben der replizierten Tabelle eine neue Spalte hinzugefügt, die etwa 10 Millionen Datensätze enthält. Wir möchten diese neue Spalte mit einem Standardwert aktualisieren.

Idealerweise funktioniert der folgende Befehl gut, um alle 10 Millionen Datensätze mit dem Standardwert als Abc zu AKTUALISIEREN :

-- UPDATE 10 Million records on Replicated Table with some DEFAULT values
UPDATE Replicated_table
SET new_column = 'Abc'

Um jedoch Auswirkungen auf die Replikation zu vermeiden, sollten wir den obigen UPDATE-Vorgang in Stapeln von 0,1 oder 0,5 Millionen Datensätzen ausführen, um Leistungsprobleme zu vermeiden.

-- UPDATE in batches to avoid performance impacts on Replication
WHILE 1 = 1
BEGIN
	UPDATE TOP(100000) Replicated_Table
	SET new_Column = 'Abc'
	WHERE new_column is NULL

	IF @@ROWCOUNT = 0
	BREAK
END

Wenn wir etwa 10 Millionen Datensätze aus einer replizierten Tabelle LÖSCHEN müssen, können wir dies in ähnlicher Weise in Stapeln tun:

-- DELETE 10 Million records on Replicated Table with some DEFAULT values
DELETE FROM Replicated_table

-- UPDATE in batches to avoid performance impacts on Replication
WHILE 1 = 1
BEGIN
	DELETE TOP(100000) Replicated_Table

	IF @@ROWCOUNT = 0
	BREAK
END

Der effiziente Umgang mit BULK INSERT, UPDATE oder DELETE kann zur Lösung der Replikationsprobleme beitragen.

Profi-Tipp :Um große Datenmengen in eine replizierte Tabelle in der Publisher-Datenbank einzufügen, verwenden Sie den IMPORT/EXPORT-Assistenten in SSMS, da er Datensätze in Stapeln von 10000 oder basierend auf der von SQL Server schneller berechneten Datensatzgröße einfügt.

Riesige Datenänderungen innerhalb einer einzigen Transaktion

Um die Datenintegrität aus der Anwendungs- oder Entwicklungsperspektive aufrechtzuerhalten, haben viele Anwendungen explizite Transaktionen für kritische Operationen definiert. Wenn jedoch viele Operationen (INSERT, UPDATE oder DELETE) innerhalb eines einzelnen Transaktionsbereichs ausgeführt werden, wartet der Protokollleseagent zunächst auf den Abschluss der Transaktion, wie wir bereits gesehen haben.

Nachdem die Transaktion von der Anwendung festgeschrieben wurde, muss der Protokollleseagent diese umfangreichen Datenänderungen scannen, die an den Transaktionsprotokollen der Herausgeberdatenbank vorgenommen wurden. Während dieses Scans können wir die Warnungen oder Informationsmeldungen im Protokollleseagenten wie

sehen

Der Protokollleseagent durchsucht das Transaktionsprotokoll nach zu replizierenden Befehlen. Ungefähr xxxxxx Protokolldatensätze wurden in Durchgang Nr. xxxx gescannt, davon wurden sie für die Replikation markiert, verstrichene Zeit xxxxxxxxx (ms)

Bevor wir die Lösung für dieses Szenario ermitteln, müssen wir verstehen, wie der Protokolllese-Agent Datensätze aus den Transaktionsprotokollen scannt und Datensätze in die Verteilungsdatenbank MSrepl_transactions einfügt und MSrepl_cmds Tabellen.

SQL Server hat intern eine Log Sequence Number (LSN) in den Transaktionsprotokollen. Der Protokolllese-Agent verwendet die LSN-Werte, um Änderungen, die für die SQL Server-Replikation gekennzeichnet sind, der Reihe nach zu scannen.

Der Protokollleseagent führt sp_replcmds aus erweiterte gespeicherte Prozedur zum Abrufen der für die Replikation markierten Befehle aus der Datenbank der Transaktionsprotokolle der Herausgeber.

Sp_replcmds akzeptiert einen Eingabeparameter namens @maxtrans um die maximale Anzahl an Transaktionen abzurufen. Der Standardwert wäre 1, was bedeutet, dass jede verfügbare Anzahl von Transaktionen aus Protokollen gescannt wird, die an die Verteilungsdatenbank gesendet werden sollen. Wenn 10 INSERT-Vorgänge über eine einzelne Transaktion ausgeführt und in der Publisher-Datenbank festgeschrieben werden, kann ein einzelner Stapel 1 Transaktion mit 10 Befehlen enthalten.

Wenn viele Transaktionen mit weniger Befehlen identifiziert werden, kombiniert der Protokollleseagent mehrere Transaktionen oder XACT Sequenznummer zu einem einzelnen Replikationsstapel. Aber es wird als ein anderes XACT gespeichert Reihenfolge Nummer in den MSRepl_transactions Tisch. Einzelne Befehle, die zu dieser Transaktion gehören, werden in den MSRepl_commands erfasst Tabelle.

Um die oben besprochenen Dinge zu überprüfen, aktualisiere ich das ModifiedDate Spalte von dbo.AWBuildVersion Tabelle bis zum heutigen Datum und sehen Sie, was passiert:

UPDATE AdventureWorks.dbo.AWBuildVersion
SET ModifiedDate  = GETDATE()

Vor der Ausführung des UPDATE überprüfen wir die Datensätze in den MSrepl_commands und MSrepl_transactions Tabellen:

Führen Sie nun das obige UPDATE-Skript aus und überprüfen Sie die Datensätze in diesen beiden Tabellen:

Ein neuer Datensatz mit der UPDATE-Zeit wurde in die MSrepl_transactions eingefügt Tabelle mit der nahegelegenen entry_time . Überprüfen des Befehls auf dieser xact_seqno zeigt die Liste der logisch gruppierten Befehle mit sp_browsereplcmds Verfahren.

Im Replikationsmonitor können wir eine einzelne UPDATE-Anweisung sehen, die unter 1 Transaktion(en) mit 1 Befehl(en) vom Herausgeber an den Verteiler erfasst wurde.

Und wir können sehen, dass derselbe Befehl im Bruchteil einer Sekunde vom Verteiler an den Abonnenten übermittelt wird. Es zeigt an, dass die Replikation ordnungsgemäß erfolgt.

Nun, wenn es eine große Anzahl von Transaktionen gibt, die in einer einzigen xact_seqno kombiniert sind , sehen wir Nachrichten wie 10 Transaktion(en) mit 5000 Befehl(en) wurden übermittelt .

Lassen Sie uns dies überprüfen, indem wir UPDATE auf 2 verschiedenen Tabellen gleichzeitig ausführen:

Wir können zwei Transaktionsaufzeichnungen in MSrepl_transactions sehen Tabelle passend zu den beiden UPDATE-Operationen und dann die Nr. der Datensätze in dieser Tabelle, die mit der Nr. übereinstimmen. der Datensätze aktualisiert.

Das Ergebnis der MSrepl_transactions Tabelle:

Das Ergebnis der MSrepl_commands Tabelle:

Wir haben jedoch festgestellt, dass diese 2 Transaktionen vom Protokollleseagenten logisch gruppiert und in einem einzigen Batch als 2 Transaktionen mit 109225 Befehlen kombiniert werden.

Aber vorher sehen wir möglicherweise Meldungen wie Delivering Replicated Transactions, xact count:1, command count 46601 .

Dies geschieht, bis der Protokolllese-Agent den vollständigen Satz von Änderungen scannt und feststellt, dass 2 UPDATE-Transaktionen vollständig aus den Transaktionsprotokollen gelesen wurden.

Nachdem die Befehle vollständig aus den Transaktionsprotokollen gelesen wurden, sehen wir, dass 2 Transaktionen mit 109225 Befehlen vom Protokollleseagenten geliefert wurden:

Da der Verteilungsagent darauf wartet, dass eine große Transaktion repliziert wird, wird möglicherweise eine Meldung wie Delivering Replicated Transactions angezeigt was darauf hinweist, dass eine riesige Transaktion repliziert wurde und wir warten müssen, bis sie vollständig repliziert wurde.

Nach der Replikation können wir auch die folgende Meldung im Verteilungsagenten sehen:

Mehrere Möglichkeiten sind hilfreich, um diese Probleme zu lösen.

Weg 1:ERSTELLEN Sie eine neue gespeicherte SQL-Prozedur

Sie müssen eine neue gespeicherte Prozedur erstellen und die Anwendungslogik darin im Bereich von Transaction einkapseln.

Sobald es erstellt ist, fügen Sie diesen Artikel der gespeicherten Prozedur zur Replikation hinzu und ändern Sie die Artikeleigenschaft Replizieren in Ausführung der gespeicherten Prozedur Option.

Es hilft, den Artikel über gespeicherte Prozeduren auf dem Abonnenten auszuführen, anstatt alle einzelnen Datenänderungen zu replizieren, die aufgetreten sind.

Sehen wir uns an, wie die Ausführung der gespeicherten Prozedur Option für Replizieren reduziert die Belastung der Replikation. Dazu können wir eine gespeicherte Testprozedur wie unten gezeigt erstellen:

CREATE procedure test_proc
AS
BEGIN
UPDATE AdventureWorks.dbo.AWBuildVersion
SET ModifiedDate  = GETDATE()

UPDATE TOP(10) Production.TransactionHistoryArchive
SET ModifiedDate  = GETDATE()

UPDATE TOP(10) Person.Person
SET ModifiedDate  = GETDATE()
END

Das obige Verfahren AKTUALISIERT einen einzelnen Datensatz in der AWBuildVersion Tabelle und jeweils 10 Datensätze im Production.TransactionHistoryArchive und Person.Person Tabellen mit insgesamt bis zu 21 Datensatzänderungen.

Nachdem Sie diese neue Prozedur sowohl auf dem Verleger als auch auf dem Abonnenten erstellt haben, fügen Sie sie der Replikation hinzu. Klicken Sie dazu mit der rechten Maustaste auf Veröffentlichung und wählen Sie den Prozedurartikel zur Replikation mit der Standardeinstellung Nur gespeicherte Prozedurdefinition Option.

Anschließend können wir die verfügbaren Datensätze in MSrepl_transactions überprüfen und MSrepl_commands Tabellen.

Lassen Sie uns nun die Prozedur in der Publisher-Datenbank ausführen, um zu sehen, wie viele Datensätze nachverfolgt werden.

Wir können Folgendes in den Verteilungstabellen MSrepl_transactions sehen und MSrepl_commands :

Drei xact_seqno wurden für drei UPDATE-Operationen in den MSrepl_transactions erstellt Tabelle, und 21 Befehle wurden in die MSrepl_commands eingefügt Tabelle.

Öffnen Sie den Replikationsmonitor und sehen Sie, ob sie als 3 verschiedene Replikationsstapel oder ein einzelner Stapel mit 3 Transaktionen zusammen gesendet werden.

Wir können diese drei xact_seqno sehen wurde als ein einziger Replikationsbatch konsolidiert. Daher können wir sehen, dass 3 Transaktionen mit 21 Befehlen erfolgreich übermittelt wurden.

Lassen Sie uns die Prozedur aus der Replikation entfernen und sie mit der zweiten Ausführung der gespeicherten Prozedur wieder hinzufügen Möglichkeit. Führen Sie nun das Verfahren aus und sehen Sie, wie die Datensätze repliziert werden.

Das Überprüfen von Datensätzen aus Verteilungstabellen zeigt die folgenden Details:

Führen Sie nun das Verfahren in der Publisher-Datenbank aus und sehen Sie, wie viele Datensätze in den Verteilungstabellen protokolliert werden. Die Ausführung einer Prozedur aktualisierte 21 Datensätze (1 Datensatz, 10 Datensätze und 10 Datensätze) wie zuvor.

Beim Überprüfen der Verteilungstabellen werden die folgenden Daten angezeigt:

Werfen wir einen kurzen Blick auf sp_browsereplcmds, um den tatsächlich empfangenen Befehl zu sehen:

Der Befehl lautet „{call „dbo“.“test_proc“ }“ die auf der Abonnentendatenbank ausgeführt wird.

Im Replikationsmonitor können wir sehen, dass nur 1 Transaktion(en) mit 1 Befehl(en) über die Replikation zugestellt wurde:

In unserem Testfall haben wir ein Verfahren mit nur 21 Datenänderungen verwendet. Wenn wir das jedoch für eine komplizierte Prozedur mit Millionen von Änderungen tun, dann ist der Stored-Procedure-Ansatz die Ausführung der Stored Procedure Option wird die Replikationslast effizient reduzieren.

Wir müssen diesen Ansatz validieren, indem wir überprüfen, ob die Prozedur über die Logik verfügt, nur denselben Satz von Datensätzen in den Herausgeber- und Abonnentendatenbanken zu aktualisieren. Andernfalls führt dies zu Dateninkonsistenzproblemen zwischen Publisher und Abonnent.

Weg 2:Konfigurieren der MaxCmdsInTran-, ReadBatchSize- und ReadBatchThreshold-Logreader-Agent-Parameter

MaxCmdsInTran – gibt die maximale Anzahl von Befehlen an, die logisch innerhalb einer Transaktion gruppiert werden können, während Daten aus den Transaktionsprotokollen der Publisher-Datenbank gelesen und in die Distributionsdatenbank geschrieben werden.

In unseren früheren Tests haben wir festgestellt, dass sich etwa 109225 Befehle in einer einzigen replikationsgenauen Sequenz angesammelt haben, was zu einer leichten Langsamkeit oder Latenz führte. Wenn wir MaxCmdsInTran setzen Parameter auf 10000, die einzelne xact-Sequenz Nummer wird in 11 aufgeteilt xact-Sequenzen, die zu einer schnelleren Übermittlung von Befehlen vom Publisher an den Distributor führen . Auch wenn diese Option dazu beiträgt, die Konflikte der Verteilungsdatenbank zu reduzieren und die Daten schneller von der Verleger- in die Abonnentendatenbank zu replizieren, sollten Sie bei der Verwendung dieser Option vorsichtig sein. Es kann dazu führen, dass die Daten vor dem Ende des ursprünglichen Transaktionsbereichs an die Abonnentendatenbank übermittelt und von den Abonnentendatenbanktabellen darauf zugegriffen wird.

ReadBatchSize – Dieser Parameter ist möglicherweise nicht hilfreich für ein einzelnes großes Transaktionsszenario. Es ist jedoch hilfreich, wenn viele, viele kleinere Transaktionen in der Publisher-Datenbank stattfinden.

Wenn die Anzahl der Befehle pro Transaktion geringer ist, kombiniert der Protokolllese-Agent mehrere Änderungen in einem einzigen Transaktionsbereich für Replikationsbefehle. Die Lesestapelgröße gibt an, wie viele Transaktionen im Transaktionsprotokoll gelesen werden können, bevor Änderungen an die Verteilungsdatenbank gesendet werden. Die Werte können zwischen 500 und 10000 liegen.

ReadBatchThreshold – gibt die Anzahl der Befehle an, die aus dem Transaktionsprotokoll der Publisher-Datenbank gelesen werden müssen, bevor sie mit einem Standardwert von 0 an den Abonnenten gesendet werden, um die vollständige Protokolldatei zu scannen. Wir können diesen Wert jedoch reduzieren, um Daten schneller zu senden, indem wir ihn auf 10000 oder 100000 Befehle wie diesen beschränken.

Weg 3:Konfigurieren der besten Werte für SubscriptionStreams-Parameter

AbonnementStreams – Gibt die Anzahl der Verbindungen an, die ein Verteilungsagent parallel ausführen kann, um Daten aus der Verteilungsdatenbank abzurufen und an die Abonnentendatenbank weiterzugeben. Der Standardwert ist 1, was nur einen Stream oder eine Verbindung von der Verteilung zur Abonnentendatenbank vorschlägt. Die Werte können zwischen 1 und 64 liegen. Wenn weitere Abonnement-Streams hinzugefügt werden, kann dies zu einer CXPACKET-Überlastung führen (mit anderen Worten, Parallelität). Daher sollten Sie beim Konfigurieren dieser Option in der Produktion vorsichtig sein.

Versuchen Sie zusammenfassend, große INSERT-, UPDATE- oder DELETE-Operationen in einer einzigen Transaktion zu vermeiden. Wenn es unmöglich ist, diese Operationen zu eliminieren, wäre die beste Option, die oben genannten Methoden zu testen und diejenige auszuwählen, die Ihren spezifischen Bedingungen am besten entspricht.

Sperren in der Verteilungsdatenbank

Die Verteilungsdatenbank ist das Herzstück der SQL Server-Transaktionsreplikation, und wenn sie nicht ordnungsgemäß gewartet wird, treten zahlreiche Leistungsprobleme auf.

Um alle empfohlenen Vorgehensweisen für die Konfiguration der Verteilungsdatenbank zusammenzufassen, müssen wir sicherstellen, dass die folgenden Konfigurationen ordnungsgemäß durchgeführt werden:

  1. Datendateien der Verteilungsdatenbanken sollten auf Laufwerken mit hoher IOPS abgelegt werden. Wenn die Publisher-Datenbank viele Datenänderungen aufweisen wird, müssen wir sicherstellen, dass die Verteilungsdatenbank auf einem Laufwerk mit hohen IOPS platziert wird. Es empfängt kontinuierlich Daten vom Protokollleseagenten und sendet Daten über den Verteilungsagenten an die Abonnentendatenbank. Alle replizierten Daten werden alle 10 Minuten über den Bereinigungsauftrag der Verteilung aus der Verteilungsdatenbank gelöscht.
  2. Konfigurieren Sie die Anfangsdateigröße und die Autogrowth-Eigenschaften der Verteilungsdatenbank mit den empfohlenen Werten basierend auf den Aktivitätsstufen der Publisher-Datenbank. Andernfalls führt dies zur Fragmentierung von Daten und Protokolldateien, was zu Leistungsproblemen führt.
  3. Beziehen Sie Verteilungsdatenbanken in die regulären Indexwartungsaufträge ein, die auf den Servern konfiguriert sind, auf denen sich die Verteilungsdatenbank befindet.
  4. Beziehen Sie Verteilungsdatenbanken in den Zeitplan für vollständige Sicherungsaufträge ein, um bestimmte Probleme zu beheben.
  5. Stellen Sie sicher, dass die Verteilungsbereinigung:Verteilung Der Job wird gemäß dem Standardzeitplan alle 10 Minuten ausgeführt. Andernfalls nimmt die Größe der Verteilungsdatenbank ständig zu und führt zu Leistungsproblemen.

Wie wir bisher bemerkt haben, sind die beteiligten Schlüsseltabellen in der Verteilungsdatenbank MSrepl_transactions und MSrepl_commands . Die Datensätze werden dort durch den Auftrag des Protokollleseagenten eingefügt, durch den Auftrag des Verteilungsagenten ausgewählt, auf die Abonnentendatenbank angewendet und dann durch den Auftrag des Verteilungsbereinigungsagenten gelöscht oder bereinigt.

Wenn die Verteilungsdatenbank nicht ordnungsgemäß konfiguriert ist, können Sitzungsblockierungen in diesen beiden Tabellen auftreten, was zu Leistungsproblemen bei der SQL Server-Replikation führt.

Wir können die folgende Abfrage für jede Datenbank ausführen, um die blockierenden Sitzungen anzuzeigen, die in der aktuellen Instanz von SQL Server verfügbar sind:

SELECT * 
FROM sys.sysprocesses
where blocked > 0
order by waittime desc

Wenn die obige Abfrage Ergebnisse zurückgibt, können wir Befehle in diesen blockierten Sitzungen identifizieren, indem wir DBCC INPUTBUFFER(spid) ausführen Konsolenbefehl und ergreifen Sie entsprechende Maßnahmen.

Korruptionsbezogene Probleme

Eine SQL Server-Datenbank verwendet ihren Algorithmus oder ihre Logik, um Daten in Tabellen zu speichern und sie in Blöcken oder Seiten zu halten. Datenbankbeschädigung ist ein Prozess, durch den sich der physische Zustand der datenbankbezogenen Dateien/Extents/Seiten vom normalen in einen instabilen oder nicht abrufbaren Zustand ändert, wodurch der Datenabruf erschwert oder unmöglich wird.

Alle SQL Server-Datenbanken sind anfällig für Datenbankbeschädigungen. Die Ursachen können sein:

  • Hardwarefehler wie Festplatten-, Speicher- oder Controller-Probleme;
  • Fehler des Serverbetriebssystems wie Probleme beim Patchen;
  • Stromausfälle, die zu einem abrupten Herunterfahren von Servern oder einem unsachgemäßen Herunterfahren der Datenbank führen.

Wenn wir Datenbanken ohne Datenverlust wiederherstellen oder reparieren können, wird die SQL Server-Replikation nicht beeinträchtigt. Wenn es jedoch während der Wiederherstellung oder Reparatur beschädigter Datenbanken zu Datenverlusten kommt, erhalten wir viele Probleme mit der Datenintegrität, die wir in unserem früheren Artikel besprochen haben.

Beschädigungen können an verschiedenen Komponenten auftreten, wie z. B.:

  • Beschädigungen von Publisher-Daten/Logfiles
  • Korruption von Abonnentendaten/Protokolldatei
  • Daten-/Protokolldatei-Korruptionen der Verteilungsdatenbank
  • Msdb-Datenbankdaten/Protokolldateibeschädigungen

If we receive a lot of data integrity issues after fixing up Corruption issues, it is recommended to remove the Replication completely, fix all Corruption issues in the Publisher, Subscriber, or Distributor database and then reconfigure Replication to fix it. Otherwise, data integrity issues will persist and lead to data inconsistency across the Publisher and Subscriber. The time required to fix the Data integrity issues in case of Corrupted databases will be much more compared to configuring Replication from scratch. Hence identify the level of Corruption encountered and take optimal decisions to resolve the Replication issues faster.

Wondering why msdb database corruption can harm Replication? Since msdb database hold all details related to SQL Server Agent Jobs including Replication Agent jobs, any corruption on msdb database will harm Replication. To recover quickly from msdb database corruptions, it is recommended to restore msdb database from the last Full Backup of msdb database. This also signifies the importance of taking Full Backups of all system databases including msdb database.

Schlussfolgerung

Thanks for successfully going through the final power-packed article about the Performance issues in the SQL Server Transactional Replication. If you have gone through all articles carefully, you should be able to troubleshoot almost any Transactional Replication-based issues and fix them out efficiently.

If you need any further guidance or have any Transactional Replication-related issues in your environment, you can reach out to me for consultation. And if I missed anything essential in this article, you are welcome to point to that in the Comments section.