sql >> Database >  >> RDS >> Sqlserver

Verkennen van wachtopties voor vergrendeling met lage prioriteit in SQL Server 2014 CTP1

SQL Server 2014 CTP1 introduceert wachtopties voor vergrendeling met lage prioriteit voor gebruik met online indexbewerkingen en partitieswitches.

Voor degenen die gebruik maken van online indexbeheer of indexpartitionering en partitiewisselingen in SQL Server 2012 Enterprise Edition, kan het zijn dat u op een gegeven moment te maken hebt gehad met het blokkeren van uw DDL-bewerking omdat deze bewerkingen nog steeds enkele vergrendelingsvereisten hebben.

Ter illustratie, stel je voor dat ik de volgende online index-reconstructie met één partitie uitvoer in SQL Server 2014 CTP1:

ALTER INDEX [ClusteredIndex_on_ps_ShipDate]ON [dbo].[FactInternetSales]REBUILD PARTITION =(37)MET (ONLINE=ON);

En laten we eens kijken naar de vergrendelingen die zijn verkregen en vrijgegeven tijdens deze herbouwbewerking met behulp van Extended Events en de volgende sessiedefinitie (dit is een doelloze sessie en ik heb de resultaten bekeken via het deelvenster "Live-gegevens bekijken" in SQL Server Management Studio):

CREATE EVENT SESSIE [Online_Index_Rebuild_Locks_Taken] OP SERVER ADD EVENT sqlserver.lock_acquired( WHERE ([object_id]=(309576141))),ADD EVENT sqlserver.lock_released( WHERE ([object_id]_MAX)WITH (=) 4096 KB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY=30 SECONDEN, MAX_EVENT_SIZE=0 KB, MEMORY_PARTITION_MODE=NONE, TRACK_CAUSALITY=UIT, STARTUP_STATE=UIT);GO

De waarde 309576141 vertegenwoordigt de object-ID van de FactInternetSales-tabel.

Mijn online index-rebuild van een enkele partitie duurde 56 seconden en na voltooiing zag ik de volgende lock-acquisitie en release-activiteit:


Activiteit vergrendelen voor online heropbouw met één partitie

Zoals je kunt zien aan de output, hoewel het opnieuw opbouwen een online operatie is, omvat het wel het verwerven van sloten in verschillende modi gedurende de levenscyclus van de operatie. Idealiter is de vergrendelingsduur minimaal (bijvoorbeeld – de tijdstempel is identiek voor de eerste SCH_S slot verworven en vrijgegeven). Maar zelfs met een minimale hoeveelheid vergrendeling kunt u zeker gelijktijdigheidsproblemen tegenkomen, afhankelijk van de transacties die worden uitgevoerd tegen de index die opnieuw wordt opgebouwd of waarnaar wordt overgeschakeld.

Ik vermeldde aan het begin van dit bericht dat Microsoft vergrendelingswachtopties met lage prioriteit heeft geïntroduceerd voor online bewerkingen en partitiewisselbewerkingen in SQL Server 2014 CTP1. Wat betreft partitie-switches, stel je voor dat ik de volgende operatie uitvoer:

WIJZIG TABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SCHAKEL PARTITIE 37 IN NAAR [AdventureWorksDW2012].[dbo].[staging_FactInternetSales];

Om de vergrendelingen te zien die voor deze operatie zijn verkregen en vrijgegeven, heb ik mijn eerder gedefinieerde Extended Event-sessie gewijzigd om de toepasselijke objecten (bron- en doeltabel) op te nemen. Ik zag het volgende:


Activiteit vergrendelen voor een partitiewisselbewerking

De overschakeling naar een lege partitie vond plaats in minder dan een seconde, maar we zien nog steeds dat SCH_S en SCH_M vergrendelingen waren vereist tijdens de levenscyclus van de bewerking op zowel de bron als de bestemming (309576141 zijnde FactInternetSales en 398624463 zijnde staging_FactInternetSales).

Dus nogmaals, hoewel de duur van de vergrendeling extreem kort kan zijn als er geen gelijktijdige transacties zijn die toegang hebben tot de objecten in kwestie, weten we dat dit niet altijd mogelijk is en dus kunnen onze online index-reconstructie en partitie-switch-operaties inderdaad worden geblokkeerd.

Dus met deze realiteit introduceert SQL Server 2014 de WAIT_AT_LOW_PRIORITY argument dat kan worden aangepast met MAX_DURATION en ABORT_AFTER_WAIT opties voor zowel de ALTER INDEX en ALTER TABLE commando's die we kunnen gebruiken voor zowel online index- als partitieschakelbewerkingen.

Wat stelt dit ons in staat om te doen? Laten we eerst eens kijken wat het gedrag was vóór SQL Server 2014. Stel je bijvoorbeeld voor dat ik de volgende transactie open en niet vastgelegd heb:

BEGIN TRANSACTIE;VERWIJDEREN [dbo].[staging_FactInternetSales];

Als ik probeerde een ALTER TABLE SWITCH uit te voeren naar de tabel staging_FactInternetSales als een bestemming in een afzonderlijke sessie, wordt ik geblokkeerd en wacht het verzoek gewoon. Specifiek voor dit voorbeeld zou ik wachten met een LCK_M_SCH_M wacht soort. Zodra ik mijn transactie terugdraai of vastleg, kan de bewerking worden voortgezet en voltooid.

Als ik nu WAIT_AT_LOW_PRIORITY van SQL Server 2014 gebruik met MAX_DURATION en ABORT_AFTER_WAIT , Ik kan een paar verschillende opties gebruiken, afhankelijk van mijn toepassingsvereisten.

MAX_DURATION stelt me ​​in staat om het aantal minuten te specificeren dat de online index-reconstructie of partitie-switch-operatie zal wachten. Als de MAX_DURATION waarde is bereikt, kunnen we instellen wat er daarna gebeurt op basis van de instelling van ABORT_AFTER_WAIT , wat een waarde kan zijn van NONE , SELF of BLOCKERS :

  • NONE betekent dat de indexbewerking zal doorgaan met het proberen van de bewerking.
  • SELF betekent dat als de MAX_DURATION is bereikt, wordt de bewerking (de online index-reconstructie of partitie-switch) geannuleerd.
  • Als BLOCKERS wordt gebruikt, zal het alle transacties doden die de online-index-reconstructie of partitie-switch-operatie blokkeren (naar mijn mening geen optie om lichtvaardig te gebruiken). BLOCKERS vereist ook ALTER ANY CONNECTION toestemming voor het verzoek dat de online-index-reconstructie of partitie-switch-bewerking uitgeeft.

De volgende codevoorbeelden demonstreren verschillende configuratievarianten.

    Standaardgedrag van vóór 2014 (wacht voor onbepaalde tijd)

      Het volgende uitvoeren zal resulteren in het gedrag dat we gewend zijn te zien pre-SQL Server 2014 - en het kan nog steeds zijn wat je wilt of verwacht voor bepaalde scenario's:

      WIJZIG TABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SCHAKEL DEEL 37 IN NAAR [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] MET (WAIT_AT_LOW_PRIORITY (MAX_DURATION =0 MINUTES, ABORT_AFTER)_WAIT =GEEN 

    Wacht 1 minuut en annuleer de DDL-bewerking

      Het volgende voorbeeld wacht 1 minuut als er een blokkerende transactie is en krijgt een "time-outperiode voor vergrendelingsverzoek overschreden" voor de SWITCH werking als de maximale duur is bereikt:

      WIJZIG TABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SCHAKEL DEEL 37 IN NAAR [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] MET (WAIT_AT_LOW_PRIORITY (MAX_DURATION =1 MINUTES, ABORT_AFTER)_WAIT =SELFTER_WAIT =ZELF 

    Wacht 1 minuut en dood de blokker(s)

      Dit voorbeeld wacht 1 minuut als er een blokkerende transactie is en stopt vervolgens de blokkerende transacties (inclusief bron of bestemming), waardoor de SWITCH bewerking te voltooien.

      WIJZIG TABEL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] SCHAKEL PARTITIE 37 OVER NAAR [AdventureWorksDW2012].[dbo].[FactInternetSales] MET (WAIT_AT_LOW_PRIORITY (MAX_DURATION =1 MINUTES, ABORT_AFTER_WAIT =BLOCK_AFTER_WAIT =BLOKKEERTJE) 

      In mijn voorbeeld van een DELETE binnen een niet-vastgelegde transactie was er geen fout in mijn SQL Server Management Studio-venster omdat ik geen actief lopende instructie had, maar een poging tot een andere instructie binnen die sessie leverde het volgende foutbericht op (omdat mijn sessie was afgebroken):

      Msg 233, niveau 20, status 0, regel 3
      Er is een fout op transportniveau opgetreden bij het verzenden van het verzoek naar de server. (provider:Shared Memory Provider, fout:0 – Er is geen proces aan de andere kant van de pijp.)

    Dood de blokker(s) onmiddellijk (bron of bestemming voor SWITCH)

      Het volgende is een voorbeeld van het onmiddellijk doden van de blocker – en in mijn voorbeeld gebeurde de omschakeling in sub-seconde en inderdaad werd de sessie die de blocker was, gedood:

      WIJZIG TABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SCHAKEL DEEL 37 IN NAAR [AdventureWorksDW2012].[dbo].[staging_FactInternetSales]MET (WAIT_AT_LOW_PRIORITY (MAX_DURATION =0 MINUTES, ABORT_AFTER_WAIT =BLOCK_AFTER_WAIT =BLOCK_AFTER_WAIT =BLOCK_AFTER_WAIT) 

Een laatste positief aspect dat ik wilde noemen...

Het SQL Server-foutlogboek biedt een standaardcontrole van het wachtgebruik voor vergrendeling met lage prioriteit, inclusief informatie over de ABORT_AFTER_WAIT operatie in lijn met de slachtofferinformatie:

Datum 9/10/2013 13:37:15
Log SQL Server (huidig ​​– 9/10/2013 12:03:00)
Bron spid51
Bericht
Proces ID 57 is gedood door een ABORT_AFTER_WAIT =BLOCKERS DDL-instructie op database_id =5, object_id =309576141.

En u ziet ook afzonderlijke vermeldingen voor de oorspronkelijke bewerking zelf. Bijvoorbeeld:

Er is een ALTER TABLE SWITCH-instructie uitgevoerd op database 'AdventureWorksDW2012', tabel 'staging_FactInternetSales' door hostnaam 'WIN-4T7S36VMSD9', hostproces-ID 1360 met doeltabel 'AdventureWorksDW2012.dbo.FactInternetSales' met behulp van de WAIT_AT_LOW_PRIORITY-opties met MAX_DITORTURATION =1 en ABDITORITY BLOKKERS. Het blokkeren van gebruikerssessies wordt beëindigd na de maximale wachttijd.

Dit soort logboekregistratie is erg handig voor het oplossen van problemen en controledoeleinden en ik ben blij om het te zien.


  1. Het Halloween-probleem – Deel 1

  2. Hoe kunnen we de grootte van de uitvoerparameter definiëren in de opgeslagen procedure?

  3. MySQL-syntaxisfoutbericht Operand moet 1 kolom(men) bevatten

  4. ORA-28040:Geen overeenkomende uitzondering voor authenticatieprotocol