Problem mit der Latenz der Transaktionsreplikation


7

Ich habe solche Datenbanksysteme geerbt. Derzeit habe ich eine Publisher-Datenbank im SQL Server 2005-Kompatibilitätsmodus unter Windows Server 2008 R2 mit SQL Server 2008R2 SP2. Der Verteiler befindet sich auf demselben Computer. Der Abonnent ist 2008R2 SP2 und die Datenbank befindet sich im SQL Server 2008-Kompatibilitätsmodus. Wir verwenden die Transaktionsreplikation. Die Isolationsstufe ist Read Committed. Der Distributor befindet sich auf dem Publisher. Auch wenn ich mit der rechten Maustaste auf Veröffentlichung klicke und das Abonnement als Pull-Abonnement angezeigt wird, spielt es meiner Meinung nach keine Rolle, da der Distributor beim Herausgeber selbst liegt. Bitte korrigieren Sie mich, wenn ich falsch liege. Das Speichersystem ist IBM Flex, das von fünf Servern einschließlich Herausgeber und Abonnent gemeinsam genutzt wird.

Seit ein paar Tagen sehe ich eine Latenz von wenigen Stunden, sie holt morgens auf und steigt nachmittags wieder an. Ich folgte https://www.mssqltips.com/sqlservertip/3598/troubleshooter-transactional-replication-latency-issues-in-sql-server/ , um genau zu sehen, was geschah. Ich habe folgende Abfrage ausgeführt.

USE distribution 
go 
EXEC Sp_browsereplcmds 
@xact_seqno_start = '<seq#>' -- seq# is same for start and end
,@xact_seqno_end = '<seq#>'
,@publisher_database_id = <publisher database id --this is different than database_id

Ich sehe, dass an einigen Tabellen, die an der Replikation beteiligt sind, angeblich massive Aktualisierungen durchgeführt werden und der Protokollleser nur das Transaktionsprotokoll scannt und erst nach Abschluss der Transaktion etwas replizieren kann. Interessanterweise kann ich weder beim Herausgeber noch beim Abonnenten eine Blockierung feststellen. Hilft es hier, die Isolationsstufe auf RCSI (Read Committed Snapshot Isolation) zu ändern? Hilft es, das Abfrageintervall auf 1 und die Lesestapelgröße auf 1000 oder 5000 zu ändern? Wie lautet der Befehl zum Ändern dieser Einstellung?

Ich habe das Standardprofil des Log Reader Agent wie folgt geändert. Abfrageintervall von 5 bis 1 und ReadBatchSize bis 5000. Dies führte fast sofort zu einer Latenz von 13 Stunden auf Null. Aber ich sehe, dass es wieder 13 Stunden waren.

Die Replikation ist synchron und ich habe keinen einzigen Hinweis auf die eigentliche Grundursache, die die Latenz verursacht hat, und jetzt ist sie verschwunden.

Antworten:


7

Ich musste endlich den Microsoft-Support anrufen und nur ein einfacher Befehl namens DBCC LOG INFO auf dem Publisher enthüllte eine mögliche Grundursache. Ich habe mehr als 8600 VLFs gesehen! und dies war die Ursache für diese Latenz. Außerdem ist unsere Protokolldatei 538 GB vorab zugeordnet.

Die Replikation war um fast 19 Stunden nicht synchron, als ich am nächsten Tag, nachdem ich den Fall mit Microsoft eröffnet hatte, um 16:00 Uhr einen weiteren Anruf von der Microsoft-Hilfe erhielt. Die Schritte waren wirklich einfach. Sichern Sie das Publisher-Datenbankprotokoll einige Male und versuchen Sie, die Protokolldatei zu verkleinern. Stellen Sie den Inkrementierungsfaktor für die Protokolldatei auf 8 GB oder 12 GB anstelle von Prozent oder 500 MB ein. Wenn die Protokolldatei das nächste Mal wächst, werden je nach Inkrementierungsfaktor 16 VLFs pro 8 GB oder 12 GB erstellt.

Nachdem ich das Protokoll gesichert hatte, konnte ich die Protokolldatei auf 350 GB und die Gesamt-VLFs auf etwa 5300 verkleinern. Noch höher. Die Latenz ist jedoch nicht gesunken. Es dauerte bis zu 22 Stunden. Ich begann mich zu fragen, ob die Anzahl der VLFs nur eine der Ursachen war. Gegen 23:30 Uhr reduzierte sich die Latenz auf ca. 7:30 Uhr und ich machte um diese Zeit mehr Speicherplatz frei, wodurch die VLFs auf 2001 reduziert wurden. Um 2:00 Uhr war die Replikation synchron. Ich beeilte mich und sicherte das Protokoll zweimal und verkleinerte die Protokolldatei auf 10 GB und vergrößerte sie wieder auf etwa 248 GB. Die Gesamtzahl der VLFs beträgt derzeit 184, und die Replikation ist seitdem synchron. Wütend! Die Protokolldatei ist fast leer.

Lassen Sie mich wissen, wenn Sie Fragen dazu haben. Ich helfe gerne. Hoffentlich muss jemand anderes Microsoft für dieses Problem nicht anrufen.


Diese Antwort überrascht mich nicht. Nach dem Aktivieren von CDC sind Protokollprobleme mit verschiedenen Funktionen zur Protokollverwendung aufgetreten. Das Update für die gesamte Latenz war die Behebung des VLF-Problems in der Primärdatenbank. Seitdem habe ich die Prüfung in unsere Wartungsroutinen implementiert.
Steve Mangiameli

6

Hilft es hier, die Isolationsstufe auf RCSI (Read Committed Snapshot Isolation) zu ändern?

Dies ist keine einfache Änderung und bringt eine zusätzliche Tempdb-Strafe mit sich. Ich würde Ihnen nicht empfehlen , nur die Isolationsstufe auf RCSI zu ändern, ohne die Vorteile in Ihrer Umgebung ordnungsgemäß zu testen und zu sehen. Vertrauen Sie mir, dies ist ein Vorschlaghammer-Ansatz.

Wir sind kürzlich auf dasselbe Problem gestoßen

Bei wenigen an der Replikation beteiligten Tabellen werden umfangreiche Aktualisierungen durchgeführt, und der Protokollleser scannt lediglich das Transaktionsprotokoll

Im Folgenden habe ich das Problem behoben:

  • Artikel als BATCHED replizieren lassen (Diese Änderung ist dynamisch und erfordert keine Neuinitialisierung ) :

    • Dies kann durch Klicken mit der rechten Maustaste auf Veröffentlichung -> Generieren von Skripten -> Überprüfen des @statusWerts erfolgen. Jeder Wert unter 16 gibt an, dass die Replikation mit TSQL ==> NOT Batched erfolgt!
    • Selbst wenn 1 Artikel nicht auf BATCH eingestellt ist, wird keiner der Artikel BATCHED, wenn Änderungen am Abonnenten vorgenommen werden.

    • Verwenden Sie unter TSQL

          EXEC sp_changearticle @publication = N'<pub name>'  -- your publication Name
                              , @article = N'<article name>'  -- your article Name
                              , @property = 'status'
                              ,  @value = 'parameters'
      
  • Erstellt einen nicht clusted Index für die Verteilungsdatenbank:

    USE [distribution]
    GO
    CREATE NONCLUSTERED INDEX [nc_MSrepl_commands_DBA]
    ON [dbo].[MSrepl_commands] ([publisher_database_id],[article_id],[xact_seqno])
    INCLUDE ([type],[originator_id])
    GO
    

Weitere Informationen zur Optimierung finden Sie unter Verbessern der Transaktionsreplikationsleistung, insbesondere unter Parameter des Verteilungsagenten und des Protokollleseragenten.

Unten ist das Skript, mit dem ich den T-Rep-Replikationsstatus finde:

USE [distribution]
-- Ref: http://www.sqlservercentral.com/blogs/basits-sql-server-tips/2012/07/25/t-sql-script-to-monitor-transactional-replication-status/

IF OBJECT_ID('Tempdb.dbo.#ReplStats') IS NOT NULL  
    DROP TABLE #ReplStats 

CREATE TABLE [dbo].[#ReplStats](
    [DistributionAgentName] [nvarchar](100) NOT NULL,
    [DistributionAgentStartTime] [datetime] NOT NULL,
    [DistributionAgentRunningDurationInSeconds] [int] NOT NULL,
    [IsAgentRunning] [bit] NULL,
    [ReplicationStatus] [varchar](14) NULL,
    [LastSynchronized] [datetime] NOT NULL,
    [Comments] [nvarchar](max) NOT NULL,
    [Publisher] [sysname] NOT NULL,
    [PublicationName] [sysname] NOT NULL,
    [PublisherDB] [sysname] NOT NULL,
    [Subscriber] [nvarchar](128) NULL,
    [SubscriberDB] [sysname] NULL,
    [SubscriptionType] [varchar](64) NULL,
    [DistributionDB] [sysname] NULL,
    [Article] [sysname] NOT NULL,
    [UndelivCmdsInDistDB] [int] NULL,
    [DelivCmdsInDistDB] [int] NULL,
    [CurrentSessionDeliveryRate] [float] NOT NULL,
    [CurrentSessionDeliveryLatency] [int] NOT NULL,
    [TotalTransactionsDeliveredInCurrentSession] [int] NOT NULL,
    [TotalCommandsDeliveredInCurrentSession] [int] NOT NULL,
    [AverageCommandsDeliveredInCurrentSession] [int] NOT NULL,
    [DeliveryRate] [float] NOT NULL,
    [DeliveryLatency] [int] NOT NULL,
    [TotalCommandsDeliveredSinceSubscriptionSetup] [int] NOT NULL,
    [SequenceNumber] [varbinary](16) NULL,
    [LastDistributerSync] [datetime] NULL,
    [Retention] [int] NULL,
    [WorstLatency] [int] NULL,
    [BestLatency] [int] NULL,
    [AverageLatency] [int] NULL,
    [CurrentLatency] [int] NULL
) ON [PRIMARY]


INSERT INTO #ReplStats 
SELECT da.[name] AS [DistributionAgentName]
      ,dh.[start_time] AS [DistributionAgentStartTime]
      ,dh.[duration] AS [DistributionAgentRunningDurationInSeconds]
      ,md.[isagentrunningnow] AS [IsAgentRunning]
      ,CASE md.[status]
        WHEN 1 THEN '1 - Started'
        WHEN 2 THEN '2 - Succeeded'
        WHEN 3 THEN '3 - InProgress'
        WHEN 4 THEN '4 - Idle'
        WHEN 5 THEN '5 - Retrying'
        WHEN 6 THEN '6 - Failed'
       END AS [ReplicationStatus]
      ,dh.[time] AS [LastSynchronized]
      ,dh.[comments] AS [Comments]
      ,md.[publisher] AS [Publisher]
      ,da.[publication] AS [PublicationName]
      ,da.[publisher_db] AS [PublisherDB]
      ,CASE 
         WHEN da.[anonymous_subid] IS NOT NULL 
            THEN UPPER(da.[subscriber_name])
       ELSE UPPER (s.[name]) END AS [Subscriber]
      ,da.[subscriber_db] AS [SubscriberDB]
      ,CASE da.[subscription_type]
        WHEN '0' THEN 'Push'  
        WHEN '1' THEN 'Pull'  
        WHEN '2' THEN 'Anonymous'  
       ELSE CAST(da.[subscription_type] AS [varchar](64)) END AS [SubscriptionType]
      ,md.[distdb] AS [DistributionDB]
      ,ma.[article]    AS [Article]
      ,ds.[UndelivCmdsInDistDB] 
      ,ds.[DelivCmdsInDistDB]
      ,dh.[current_delivery_rate] AS [CurrentSessionDeliveryRate]
      ,dh.[current_delivery_latency] AS [CurrentSessionDeliveryLatency]
      ,dh.[delivered_transactions] AS [TotalTransactionsDeliveredInCurrentSession]
      ,dh.[delivered_commands] AS [TotalCommandsDeliveredInCurrentSession]
      ,dh.[average_commands] AS [AverageCommandsDeliveredInCurrentSession]
      ,dh.[delivery_rate] AS [DeliveryRate]
      ,dh.[delivery_latency] AS [DeliveryLatency]
      ,dh.[total_delivered_commands] AS [TotalCommandsDeliveredSinceSubscriptionSetup]
      ,dh.[xact_seqno] AS [SequenceNumber]
      ,md.[last_distsync] AS [LastDistributerSync]
      ,md.[retention] AS [Retention]
      ,md.[worst_latency] AS [WorstLatency]
      ,md.[best_latency] AS [BestLatency]
      ,md.[avg_latency] AS [AverageLatency]
      ,md.[cur_latency] AS [CurrentLatency]
FROM [distribution]..[MSdistribution_status] ds 
INNER JOIN [distribution]..[MSdistribution_agents] da
    ON da.[id] = ds.[agent_id]                          
INNER JOIN [distribution]..[MSArticles] ma 
    ON ma.publisher_id = da.publisher_id 
        AND ma.[article_id] = ds.[article_id]
INNER JOIN [distribution]..[MSreplication_monitordata] md
    ON [md].[job_id] = da.[job_id]
INNER JOIN [distribution]..[MSdistribution_history] dh
    ON [dh].[agent_id] = md.[agent_id] 
        AND md.[agent_type] = 3
INNER JOIN [master].[sys].[servers]  s
    ON s.[server_id] = da.[subscriber_id] 
--Created WHEN your publication has the immediate_sync property set to true. This property dictates 
--whether snapshot is available all the time for new subscriptions to be initialized. 
--This affects the cleanup behavior of transactional replication. If this property is set to true, 
--the transactions will be retained for max retention period instead of it getting cleaned up
--as soon as all the subscriptions got the change. 
WHERE da.[subscriber_db] <> 'virtual' 
    AND da.[anonymous_subid] IS NULL
    AND dh.[start_time] = (SELECT TOP 1 start_time
                            FROM [distribution]..[MSdistribution_history] a
                            JOIN [distribution]..[MSdistribution_agents] b
                            ON a.[agent_id] = b.[id] AND b.[subscriber_db] <> 'virtual'
                            WHERE [runstatus] <> 1
                            ORDER BY [start_time] DESC)
    AND dh.[runstatus] <> 1

SELECT 'Transactional Replication Summary' AS [Comments];
SELECT [DistributionAgentName]
      ,[DistributionAgentStartTime]
      ,[DistributionAgentRunningDurationInSeconds]
      ,[IsAgentRunning]
      ,[ReplicationStatus]
      ,[LastSynchronized]
      ,[Comments]
      ,[Publisher]
      ,[PublicationName]
      ,[PublisherDB]
      ,[Subscriber]
      ,[SubscriberDB]
      ,[SubscriptionType]
      ,[DistributionDB]
      ,SUM([UndelivCmdsInDistDB]) AS [UndelivCmdsInDistDB]
      ,SUM([DelivCmdsInDistDB]) AS [DelivCmdsInDistDB]
      ,[CurrentSessionDeliveryRate]
      ,[CurrentSessionDeliveryLatency]
      ,[TotalTransactionsDeliveredInCurrentSession]
      ,[TotalCommandsDeliveredInCurrentSession]
      ,[AverageCommandsDeliveredInCurrentSession]
      ,[DeliveryRate]
      ,[DeliveryLatency]
      ,[TotalCommandsDeliveredSinceSubscriptionSetup]
      ,[SequenceNumber]
      ,[LastDistributerSync]
      ,[Retention]
      ,[WorstLatency]
      ,[BestLatency]
      ,[AverageLatency]
      ,[CurrentLatency]
FROM #ReplStats
GROUP BY [DistributionAgentName]
        ,[DistributionAgentStartTime]
        ,[DistributionAgentRunningDurationInSeconds]
        ,[IsAgentRunning]
        ,[ReplicationStatus]
        ,[LastSynchronized]
        ,[Comments]
        ,[Publisher]
        ,[PublicationName]
        ,[PublisherDB]
        ,[Subscriber]
        ,[SubscriberDB]
        ,[SubscriptionType]
        ,[DistributionDB]
        ,[CurrentSessionDeliveryRate]
        ,[CurrentSessionDeliveryLatency]
        ,[TotalTransactionsDeliveredInCurrentSession]
        ,[TotalCommandsDeliveredInCurrentSession]
        ,[AverageCommandsDeliveredInCurrentSession]
        ,[DeliveryRate]
        ,[DeliveryLatency]
        ,[TotalCommandsDeliveredSinceSubscriptionSetup]
        ,[SequenceNumber]
        ,[LastDistributerSync]
        ,[Retention]
        ,[WorstLatency]
        ,[BestLatency]
        ,[AverageLatency]
        ,[CurrentLatency]

SELECT 'Transactional Replication Summary Details' AS [Comments];
SELECT [Publisher]
      ,[PublicationName]
      ,[PublisherDB]
      ,[Article]
      ,[Subscriber]
      ,[SubscriberDB]
      ,[SubscriptionType]
      ,[DistributionDB]
      ,SUM([UndelivCmdsInDistDB]) AS [UndelivCmdsInDistDB]
      ,SUM([DelivCmdsInDistDB]) AS [DelivCmdsInDistDB]
FROM #ReplStats
GROUP BY [Publisher]
        ,[PublicationName]
        ,[PublisherDB]
        ,[Article]
        ,[Subscriber]
        ,[SubscriberDB]
        ,[SubscriptionType]
        ,[DistributionDB]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.