Varför din synkrona SQL-commit väntar på VPN-rundturen
En synkron commit i en tillgänglighetsgrupp omfattar härdningen av fjärrloggen. Mät den vägen innan du klandrar bandbredden eller byter läge.
Skrivlatensen sköt i höjden efter att en replika flyttats till den andra platsen, och tunneln är den nyaste komponenten, så den får skulden. Tunneln kan vara oskyldig: inne i en tillgänglighetsgrupp med synkron commit kan den primära inte kvittera en commit förrän en fjärrloggskrivning är klar, så varje transaktion betalar en rundtur, oavsett hur många megabit förbindelsen kan bära. Genomströmning mäter byte per sekund, latens mäter hur lång tid ett utbyte tar, och en commit behöver bara ett litet utbyte för att bli klar. Ett tal avgör diskussionen: varaktigheten för en liten transaktions commit, mätt inne i tillgänglighetsdatabasen och sedan igen mot en lokal tabell på samma instans.
Vad den primära egentligen väntar på
Vid synkron commit håller den primära kvar commit-kvittensen tills partnern bekräftar att dess loggposter är härdade. Härdade betyder varaktigt skrivna till den sekundära transaktionsloggen, inte omkört i dess datasidor. Redo kan ligga minuter efter utan att lägga till en enda millisekund till den primäras commit.
Microsofts dokumentation om tillgänglighetslägena går igenom den handskakningen och beskriver vad plattformen gör när en partner faller bort. En replika som är markerad som synkron är en regel om att vänta, inte ett stående löfte att det finns en frisk fjärrkopia för varje commit. Den frånkopplade vägen definieras separat, och det är inte bara att commit misslyckas.
Så väntan du ser är en summa: loggtransport, schemaläggning på båda värdarna och skrivningen till fjärrlagringen. En sekundär med mättad loggvolym lägger till tid som inget hastighetstest visar. Den disken mäts sällan när klagomålet nämner VPN:en.
Bandbredd är inte rundtursfördröjning
Ett hastighetstest översvämmar vägen kort och rapporterar en hastighet. En commit frågar efter något smalare: hur lång tid ett litet meddelande tar att nå andra sidan, sparas och komma tillbaka. Vägens längd, köer och paketförlust bestämmer det talet, och ingen av dem förbättras när leverantören höjer taket.
En «snabb» tunnel kan därför lägga till en synlig straffavgift på en skrivtung arbetsbelastning byggd av många små sekventiella transaktioner. Samma totala mängd byte fördelad på tusen commits betalar rundturen tusen gånger; en bulköverföring betalar den en gång.
Be nätverkets ägare om fördröjning och förlust mätta över själva replikvägen under representativ last. En ping från en kontorsbärbar dator till VPN-gatewayen, eller ett hastighetstest till en närliggande nod, tillskriver nästan ingenting till vägen som loggen faktiskt reser. Se till att mätfönstret överlappar timmarna då skrivningen är långsam.
Läs replikans tillstånd innan du ändrar något
Börja med vad instanserna rapporterar om sig själva, eftersom de två sidorna kan vara oeniga om hur frisk partnerskapet är och ett genomsnitt på instrumentpanelen döljer vilken kö som rör sig. Frågorna nedan svarar på olika frågor: en läser replikeringstillståndet per databas, den andra läser hur varje replika är konfigurerad. Kör båda innan du rör ett läge.
SELECT ag.name AS ag_name, drs.database_id, drs.synchronization_state_desc,
drs.log_send_queue_size, drs.redo_queue_size, drs.secondary_lag_seconds
FROM sys.dm_hadr_database_replica_states AS drs
JOIN sys.availability_groups AS ag ON ag.group_id = drs.group_id;
SELECT ar.replica_server_name, ar.availability_mode_desc, ar.failover_mode_desc
FROM sys.availability_replicas AS ar;
Det första resultatet skiljer loggtransport från redo. log_send_queue_size som stiger medan redo_queue_size står platt betyder att loggen inte har anlänt; det motsatta betyder att den har anlänt och att uppspelningen ligger efter. Bara det första fallet sitter på commit-vägen.
Det andra resultatet bekräftar vilka replikor som faktiskt är konfigurerade som du antar, eftersom ett läge som ändrades under en tidigare incident tenderar att förbli ändrat och odokumenterat. Läs raden du bryr dig om i stället för gruppens standard: availability_mode_desc och failover_mode_desc gäller per replika. secondary_lag_seconds finns bara på SQL Server 2016 och senare, så en äldre version lämnar dig med bara kolumnerna för sändningskön och redo.
Mät sedan en representativ skrivning i stället för att lita på ett instrumentpanelsgenomsnitt. Kör blocket nedan i tillgänglighetsdatabasen och kör det sedan igen mot samma tabellform i en databas utanför gruppen på samma instans. Skillnaden mellan de två varaktigheterna är ett grovt pris för fjärrloggen, och i en diskussion med nätverksteamet håller den mycket bättre än en graf. Ändra sedan en variabel i taget, annars slutar skillnaden att betyda något.
IF OBJECT_ID('dbo.CommitProbe') IS NULL
CREATE TABLE dbo.CommitProbe (probe_id int PRIMARY KEY, touched_at datetime2(3));
IF NOT EXISTS (SELECT 1 FROM dbo.CommitProbe WHERE probe_id = 1)
INSERT INTO dbo.CommitProbe (probe_id) VALUES (1);
SET STATISTICS TIME ON;
BEGIN TRANSACTION;
UPDATE dbo.CommitProbe SET touched_at = SYSUTCDATETIME() WHERE probe_id = 1;
COMMIT TRANSACTION;
SET STATISTICS TIME OFF;
Vad asynkron commit köper, och vad den kostar
Med asynkron commit slutar den primära att vänta på bekräftelsen av fjärrhärdningen, så rundturen lämnar commit-vägen. Commit-latensen faller och den sekundära står fri att ligga efter i en omfattning som ingen kontrollerar. Det är en verklig lösning på väntan och en verklig ändring av löftet.
Priset är ett beslut om återställningspunkten. Om den primära dör innan loggen når ett redundansväxlingsmål som du faktiskt kan använda, kastar flytten av tjänsten till den asynkrona kopian transaktioner som applikationen redan rapporterat som committade. Ingen konfigurationsdialog framställer det så, eftersom det är en affärsfråga om acceptabel förlust, inte en prestandainställning. Skriv ned det tolererade förlustfönstret före incidenten, inte under den.
Kom överens om läget med den som äger data, skriftligt, tillsammans med redundansväxlingsproceduren för fallet då det föredragna målet inte är tillgängligt. Synkron i ett designdokument är inte en driftmanual, och asynkron är inte en licens att sluta bevaka köerna.
Välj en lösning du kan försvara i efterhand
Det finns fyra ärliga alternativ. Skär bort undvikbara commit-rundturer där applikationens semantik tillåter batchning; åtgärda en uppmätt flaskhals i transport eller lagring, vilket kan innebära en snabbare loggvolym på den sekundära i stället för ett större rör; flytta replikan närmare så att rundturen krymper; eller lätta på skyddspolicyn och acceptera ett bredare förlustfönster. Var och en köper latens genom att spendera något annat, och den fjärde spenderar hållbarhet. Namnge utgiften innan du väljer.
Bestäm med arbetsbelastningens latensmål och dess hållbarhetskrav framför dig samtidigt, eftersom optimering av det ena tyst spenderar det andra. Kör sedan samma transaktion igen som du mätte före ändringen. En lösning som inte kan flytta det talet är en gissning med en ändringsbiljett.
Spara före- och eftermätningarna i ändringsloggen. Annars upprepar nästa person som ser långsamma skrivningar utredningen från början och börjar igen med att skylla på tunneln.