Konfigurera distribuerade transaktioner för en Always On-tillgänglighetsgrupp

Gäller för:SQL Server

SQL Server 2017 (14.x) och senare versioner stödjer alla distribuerade transaktioner inklusive databaser i en tillgänglighetsgrupp. Den här artikeln förklarar hur man konfigurerar en tillgänglighetsgrupp för distribuerade transaktioner

För att garantera distribuerade transaktioner måste tillgänglighetsgruppen konfigureras för att registrera databaser som distribuerade transaktionsresurshanterare.

Note

SQL Server 2016 (13.x) Service Pack 2 och senare versioner ger fullt stöd för distribuerade transaktioner i tillgänglighetsgrupper. I SQL Server 2016 (13.x) Service Pack 1 och tidigare versioner stöds inte transaktioner över databaser (det vill säga transaktioner med databaser på samma SQL Server-instans) som involverar en databas i en tillgänglighetsgrupp. SQL Server 2017 (14.x) har inte denna begränsning.

I SQL Server 2016 (13.x) är konfigurationsstegen desamma som i SQL Server 2017 (14.x).

I en distribuerad transaktion arbetar klientapplikationer med Microsoft Distributed Transaction Coordinator (MSDTC eller DTC) för att garantera transaktionell konsekvens över flera datakällor. DTC är en tjänst som finns tillgänglig på stödda operativsystem baserade på Windows Server. För en distribuerad transaktion är DTC transaktionskoordinator. Normalt är en SQL Server-instans resurshanteraren. När en databas är i en tillgänglighetsgrupp behöver varje databas vara sin egen resurshanterare.

SQL Server förhindrar inte distribuerade transaktioner för databaser i en tillgänglighetsgrupp – även när tillgänglighetsgruppen inte är konfigurerad för distribuerade transaktioner. Men när en tillgänglighetsgrupp inte är konfigurerad för distribuerade transaktioner kan failover misslyckas i vissa situationer. Specifikt kanske den nya primära replika SQL Server-instansen inte kan få transaktionsresultatet från DTC. För att möjliggöra för SQL Server-instansen att få resultatet av osäkra transaktioner från DTC efter failover, konfigurera tillgänglighetsgruppen för distribuerade transaktioner.

DTC är inte involverad i bearbetning av tillgänglighetsgrupper om inte en databas också är medlem i ett failover-kluster. Inom en tillgänglighetsgrupp upprätthålls konsistensen mellan replikerna av tillgänglighetsgruppens logik: Primären slutför inte commit och bekräftar inte commit till anroparen förrän sekundären bekräftar att loggposterna har bevarats i varaktig lagring. Först då förklarar primären transaktionen slutförd. I asynkront läge väntar vi inte på att sekundären ska acka, och det finns uttryckligen en risk för förlust av en liten mängd data.

Förutsättningar

Innan du konfigurerar en tillgänglighetsgrupp för att stödja distribuerade transaktioner måste du uppfylla följande förutsättningar:

  • Alla instanser av SQL Server som deltar i den distribuerade transaktionen måste vara SQL Server 2016 (13.x) eller senare versioner.

  • Tillgänglighetsgrupper måste köras på Windows Server 2012 R2 eller nyare versioner. För Windows Server 2012 R2 måste du installera uppdateringen i KB3090973.

Skapa en tillgänglighetsgrupp för distribuerade transaktioner

Konfigurera en tillgänglighetsgrupp för att stödja distribuerade transaktioner. Ställ in tillgänglighetsgruppen så att varje databas kan registreras som resurshanterare. Den här artikeln förklarar hur man konfigurerar en tillgänglighetsgrupp så att varje databas kan vara en resurshanterare i DTC.

Du kan skapa en tillgänglighetsgrupp för distribuerade transaktioner på SQL Server 2016 (13.x) eller senare versioner. För att skapa en tillgänglighetsgrupp för distribuerade transaktioner, inkludera DTC_SUPPORT = PER_DB i definitionen av tillgänglighetsgruppen. Följande skript skapar en tillgänglighetsgrupp för distribuerade transaktioner.

CREATE AVAILABILITY
GROUP MyAG
WITH (DTC_SUPPORT = PER_DB)
FOR DATABASE DB1,
    DB2 REPLICA
ON 'Server1' WITH (
   ENDPOINT_URL = 'TCP://SERVER1.corp.com:5022',
   AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
   FAILOVER_MODE = AUTOMATIC
),
'Server2' WITH (
   ENDPOINT_URL = 'TCP://SERVER2.corp.com:5022',
   AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
   FAILOVER_MODE = AUTOMATIC
);

Note

Det föregående skriptet är ett enkelt exempel på en tillgänglighetsgrupp och är inte designat för någon specifik produktionsmiljö.

Ändra en tillgänglighetsgrupp för distribuerade transaktioner

Du kan ändra en tillgänglighetsgrupp för distribuerade transaktioner på SQL Server 2017 (14.x) eller senare versioner. För att ändra en tillgänglighetsgrupp för distribuerade transaktioner, inkludera DTC_SUPPORT = PER_DB i skriptet ALTER AVAILABILITY GROUP . Exempelskriptet ändrar tillgänglighetsgruppen för att stödja distribuerade transaktioner.

ALTER AVAILABILITY GROUP MyaAG
SET (DTC_SUPPORT = PER_DB);

Note

I SQL Server 2016 (13.x) Service Pack 2 och senare versioner kan du ändra en tillgänglighetsgrupp för distribuerade transaktioner. För SQL Server 2016 (13.x) versioner före Service Pack 2 behöver du ta bort och återskapa tillgänglighetsgruppen med inställningenDTC_SUPPORT = PER_DB.

För att inaktivera distribuerade transaktioner, använd följande Transact-SQL kommando:

ALTER AVAILABILITY GROUP MyaAG
SET (DTC_SUPPORT = NONE);

Distribuerade transaktioner – tekniska koncept

En distribuerad transaktion sträcker sig över två eller fler databaser. Som transaktionshanterare koordinerar DTC transaktionen mellan SQL Server-instanser och andra datakällor. Varje instans av SQL Server-databasmotorn kan fungera som resurshanterare. När en tillgänglighetsgrupp konfigureras med DTC_SUPPORT = PER_DB, kan databaserna fungera som resurshanterare. För mer information, se MSDTC-dokumentationen.

En transaktion med två eller fler databaser i en enda instans av databasmotorn är faktiskt en distribuerad transaktion. Instansen hanterar den distribuerade transaktionen internt. för användaren fungerar den som en lokal transaktion. SQL Server 2017 (14.x) uppgraderar alla transaktioner över databaser till DTC när databaser är i en tillgänglighetsgrupp konfigurerad med DTC_SUPPORT = PER_DB – även inom en enda instans av SQL Server.

I applikationen hanteras en distribuerad transaktion på ungefär samma sätt som en lokal transaktion. I slutet av transaktionen begär programmet att transaktionen antingen bekräftas eller återställs. Transaktionshanteraren måste hantera en distribuerad commit på ett annat sätt, för att minimera risken att ett nätverksfel kan leda till att vissa resurshanterare lyckas committa, medan andra rullar tillbaka transaktionen. Detta uppnås genom att hantera incheckningsprocessen i två faser (förberedelsefasen och incheckningsfasen), som kallas för en tvåfasincheckning.

  • Förberedelsefas

    När transaktionshanteraren tar emot en begäran om godkännande skickar den ett förberedande kommando till alla resurshanterarna som är inblandade i transaktionen. Varje resurshanterare gör sedan allt som krävs för att göra transaktionen hållbar, och alla buffertar som håller loggbilder för transaktionen rensas till disken. När varje resurshanterare slutför förberedelsefasen returnerar den framgång eller misslyckande i förberedelsefasen till transaktionshanteraren.

  • Incheckningsfas

    Om transaktionshanteraren får lyckade förberedelser från alla resurshanterare, skickar den bekräftelsekommandon till varje resurshanterare. Resurshanterna kan sedan slutföra åtagandet. Om alla resurshanterare rapporterar ett lyckat åtagande skickar transaktionshanteraren sedan en bekräftelse av framgång till programmet. Om någon resurshanterare rapporterade att det inte gick att förbereda skickar transaktionshanteraren ett återställningskommando till varje resurshanterare och anger att incheckningen till programmet misslyckades.

Detaljerade steg

Följande lista förklarar hur applikationen fungerar med DTC för att slutföra distribuerade transaktioner.

  1. SQL Server-instansen deltar i DTC-transaktionen. Detta kan hända när det finns mer än en resurshanterare i transaktionen eller om klienten begär att en transaktion ska uppgraderas till DTC-transaktion.
  2. Klienten gör viss arbetsinsats i SQL Server-instansen under DTC-transaktionen.
  3. Klienten genomför eller avbryter DTC-transaktionen.
    • Om klienten begär avbrott avbryts transaktionen omedelbart.
    • Om klienten utfärdar commit startar DTC tvåfas-commitprotokollet genom att be alla resurshanterare i transaktionen att förbereda transaktionen.
  4. DTC informerar alla resurshanterare att genomföra transaktionen efter att alla resurshanterare framgångsrikt bekräftat förberedelsefasen. Om något förhindrar en lyckad bekräftelse, avbryter DTC transaktionen.

Effekter av att konfigurera en tillgänglighetsgrupp för distribuerade transaktioner

Varje enhet som deltar i en distribuerad transaktion kallas en resurshanterare. Exempel på resursförvaltare inkluderar:

  • En SQL Server-instans.
  • En databas i en tillgänglighetsgrupp som är konfigurerad för distribuerade transaktioner.
  • DTC-tjänst – kan också vara en transaktionshanterare.
  • Andra datakällor.

För att delta i distribuerade transaktioner ansluter sig en instans av SQL Server till en DTC. Normalt sett ansluter SQL Server-instansen till DTC på den lokala servern. Varje instans av SQL Server skapar en resurshanterare med en unik resurshanteraridentifierare (RMID) och registrerar den hos DTC. I standardkonfigurationen använder alla databaser på en instans av SQL Server samma RMID.

När en databas finns i en tillgänglighetsgrupp kan den läs- och skrivbara kopian av databasen – eller den primära repliken – flyttas till en annan instans av SQL Server. För att stödja distribuerade transaktioner under denna rörelse bör varje databas fungera som en separat resurshanterare och ha en unik RMID. När en tillgänglighetsgrupp har DTC_SUPPORT = PER_DB, skapar SQL Server en resurshanterare för varje databas och registrerar sig hos DTC med en unik RMID. I denna konfiguration fungerar databasen som resurshanterare för DTC-transaktioner.

Important

DTC har en gräns på 32 värvningar per distribuerad transaktion. Eftersom varje databas inom en tillgänglighetsgrupp registrerar sig separat hos DTC, kan du få följande felmeddelande om din transaktion involverar fler än 32 databaser när SQL Server försöker registrera den 33:e databasen:

Enlist operation failed: 0x8004d101(XACT_E_TOOMANY_ENLISTMENTS). SQL Server couldn't register with Microsoft Distributed Transaction Coordinator (MSDTC) as a resource manager for this transaction. The transaction might have been stopped by the client or the resource manager.

Mer information om distribuerade transaktioner i SQL Server finns i distribuerade transaktioner

Hantera olösta transaktioner

Resultatet för de aktiva transaktionerna som finns under RHID-ändringen kan inte återställas efter en failover. Detta beror på att RMID SQL Server som används för att registrera sig och RMID SQL Server som används för återställning är olika. RHID-förändringen kan ske i följande fall:

  • Byt DTC_SUPPORT till en tillgänglighetsgrupp.
  • Lägg till eller ta bort en databas från en tillgänglighetsgrupp.
  • Lämna en tillgänglighetsgrupp.

I föregående fall, om den primära repliken växlar över till en ny instans av SQL Server, försöker instansen kontakta DTC för att fastställa transaktionens utfall. DTC kan inte returnera resultatet eftersom den RMID:n som databasen använder för att få utfallet för osäkra transaktioner under återställning inte registrerades tidigare. Därför går databasen in i MISSTÄNKT-tillstånd.

Den nya SQL Server-felloggen har en post som i följande exempel:

Microsoft Distributed Transaction Coordinator (MSDTC)
failed to reenlist citing that the database RMID does
not match the RMID [xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx]
associated with the transaction.  Please manually resolve
the transaction.

SQL Server detected a DTC/KTM in-doubt transaction with UOW
{yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy}.Please resolve it
following the guideline for Troubleshooting DTC Transactions.

Föregående exempel visar att DTC inte kunde återregistrera databasen från den nya primära repliken i transaktionen som skapades efter failover. SQL Server-instansen kan inte avgöra resultatet av den distribuerade transaktionen, så den markerar databasen som misstänkt. Transaktionen markeras som en arbetsenhet (UOW) och refereras till med en GUID. För att återställa databasen måste du manuellt antingen genomföra eller rulla tillbaka transaktionen.

Varning

När du manuellt committar eller rullar tillbaka en transaktion kan det påverka en applikation. Kontrollera att åtgärden att genomföra eller återställa överensstämmer med kraven för din applikation.

Kör endast ett av följande skript:

  • För att committa transaktionen, uppdatera och kör följande skript – ersätt med yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy den osäkra transaktionen UOW från föregående felmeddelande, och kör:

    KILL 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy' WITH COMMIT;
    
  • För att rulla tillbaka transaktionen, uppdatera och kör följande skript – ersätt med yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy den osäkra transaktionen UOW från föregående felmeddelande, och kör:

    KILL 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy' WITH ROLLBACK;
    

När du har genomfört eller återställt transaktionen kan du använda ALTER DATABASE för att ställa databasen online. Uppdatera och kör följande skript – sätt databasnamnet för namnet på den misstänkta databasen:

ALTER DATABASE [DB1] SET ONLINE;

För mer information om hur man löser transaktioner utan tvekan, se Lös transaktioner manuellt.