sql >> Database >  >> RDS >> Database

Meer transactielogvet bijsnijden

In mijn vorige bericht over het stroomlijnen van de bewerkingen van het transactielogboek, heb ik twee van de meest voorkomende oorzaken besproken van het genereren van extra logrecords:dood gewicht van ongebruikte niet-geclusterde indexen en paginasplitsingsbewerkingen (die indexfragmentatie veroorzaken). Ervan uitgaande dat je dat bericht hebt gelezen, heb ik gezegd dat er meer subtiele problemen zijn die schadelijk kunnen zijn voor de prestaties van transactielogboeken, en ik ga deze hier bespreken.

Veel, heel veel kleine transacties

Om de zoveel tijd spoelt SQL Server een deel van het transactielogboek naar schijf. Een log-flush vindt plaats wanneer:

  • Er wordt een transactie-vastleggingslogrecord gegenereerd.
  • Aan het einde van het terugdraaien van een transactie wordt een transactie-afbreeklogboek gegenereerd.
  • 60KB aan logrecords is gegenereerd sinds de vorige logspoeling.

De kleinst mogelijke log-flush is een enkel logblok van 512 bytes. Als alle transacties in een werkbelasting erg klein zijn (bijvoorbeeld door een enkele, kleine tabelrij in te voegen), zullen er veel log-flushes van minimale grootte plaatsvinden. Log-flushes worden asynchroon uitgevoerd om een ​​behoorlijke doorvoer van transactielogboeken mogelijk te maken, maar er is een vaste limiet van 32 gelijktijdige log-flush I/O's tegelijk (verhoogd tot 112 op SQL Server 2012).

Er zijn twee mogelijke effecten die dit kan hebben:

  1. Op een traag presterend I/O-subsysteem kan het volume van kleine schrijfacties in transactielogboeken het I/O-subsysteem overweldigen, wat kan leiden tot schrijfbewerkingen met hoge latentie en de daaropvolgende verslechtering van de verwerkingscapaciteit van transactielogboeken. Deze situatie kan worden geïdentificeerd door hoge schrijfvertragingen voor het transactielogbestand in de uitvoer van sys.dm_io_virtual_file_stats (zie de demo-links bovenaan het vorige bericht)
  2. Op een goed presterend I/O-subsysteem kunnen de schrijfbewerkingen extreem snel worden voltooid, maar de limiet van 32 gelijktijdige log-flush I/O's creëert een knelpunt bij het proberen om de logrecords duurzaam op schijf te maken. Deze situatie kan worden geïdentificeerd door lage schrijfvertragingen en een vrijwel constant aantal uitstaande transactielogboeken van bijna 32 in de geaggregeerde uitvoer van sys.dm_io_pending_io_requests (zie dezelfde demo-links).

In beide gevallen kan het langer maken van transacties (wat erg contra-intuïtief is!) de frequentie van het leegmaken van transactielogboeken verminderen en de prestaties verbeteren. Bovendien, in geval #1, kan het helpen om naar een beter presterend I/O-subsysteem te gaan, maar dit kan leiden tot geval #2. In geval #2, als de transacties niet langer kunnen worden uitgevoerd, is het enige alternatief om de werklast te verdelen over meerdere databases om de vaste limiet van 32 gelijktijdige log-flush I/O's te omzeilen of om te upgraden naar SQL Server 2012 of hoger.

Automatische groei transactielogboek

Telkens wanneer er nieuwe ruimte aan het transactielogboek wordt toegevoegd, moet deze op nul worden geïnitialiseerd (nullen wegschrijven om het eerdere gebruik van dat gedeelte van de schijf te overschrijven), ongeacht of de functie voor onmiddellijke bestandsinitialisatie is ingeschakeld of niet. Dit is van toepassing op creatie, handmatige groei en automatische groei van het transactielogboek. Terwijl de nul-initialisatie plaatsvindt, kunnen logboekrecords niet naar het logboek worden gewist, dus automatische groei tijdens een werkbelasting die gegevens verandert, kan leiden tot een merkbare daling van de doorvoer, vooral als de automatische groeigrootte is ingesteld op groot ( zeg gigabytes, of links op de standaard 10%).

Automatische groei moet worden vermeden, indien mogelijk, door het transactielogboek te laten wissen, zodat er altijd vrije ruimte is die opnieuw kan worden gebruikt voor nieuwe logboekrecords. Het wissen van transactielogboeken (ook bekend als het afkappen van transactielogboeken, niet te verwarren met het verkleinen van transactielogboeken) wordt uitgevoerd door back-ups van transactielogboeken bij gebruik van de herstelmodi Volledig of Bulksgewijs geregistreerd, en door controlepunten bij gebruik van de modus Eenvoudig herstel.

Het wissen van logboeken kan alleen plaatsvinden als niets vereist dat de logboekrecords in het gedeelte van het transactielogboek worden gewist. Een veelvoorkomend probleem dat het wissen van logboeken verhindert, is het hebben van langlopende transacties. Totdat een transactie wordt vastgelegd of teruggedraaid, zijn alle logboekrecords vanaf het begin van de transactie vereist voor het geval de transactie wordt teruggedraaid - inclusief alle logboekrecords van andere transacties die worden afgewisseld met die van de langlopende transactie. Langlopende transacties kunnen bijvoorbeeld het gevolg zijn van een slecht ontwerp, code die wacht op menselijke invoer of oneigenlijk gebruik van geneste transacties. Deze kunnen allemaal worden vermeden zodra ze als een probleem zijn geïdentificeerd.

Hier en hier kun je hier meer over lezen.

Functies voor hoge beschikbaarheid

Sommige functies met hoge beschikbaarheid kunnen het wissen van transactielogboeken ook vertragen:

  • Databasespiegeling en beschikbaarheidsgroepen kunnen bij asynchroon werken een wachtrij opbouwen van logboekrecords die nog niet naar de redundante databasekopie zijn verzonden. Deze logrecords moeten worden bewaard totdat ze worden verzonden, waardoor het wissen van transactielogs wordt vertraagd.
  • Transactionele replicatie (en ook Change Data Capture) vertrouwt op een Log Reader Agent-taak om het transactielogboek periodiek te scannen op transacties die een tabel wijzigen die in een replicatiepublicatie is opgenomen. Als de Log Reader Agent om wat voor reden dan ook achterloopt, of met opzet niet vaak wordt uitgevoerd, moeten alle logboekrecords die niet door de taak zijn gescand, worden bewaard, waardoor het wissen van het transactielogboek wordt vertraagd.

Bij het uitvoeren in de synchrone modus kunnen database-mirroring en beschikbaarheidsgroepen andere problemen met het logboekregistratiemechanisme veroorzaken. Met behulp van synchrone database-mirroring als voorbeeld, kan elke transactie die op de principal wordt vastgelegd, niet daadwerkelijk terugkeren naar de gebruiker of toepassing totdat alle gegenereerde logrecords met succes naar de mirrorserver zijn verzonden, wat een vastleggingsvertraging voor de principal toevoegt. Als de gemiddelde transactieomvang lang is en de vertraging kort, is dit misschien niet merkbaar, maar als de gemiddelde transactie erg kort is en de vertraging vrij lang, kan dit een merkbaar effect hebben op de werklastdoorvoer. In dat geval moeten ofwel de prestatiedoelen van de workload worden gewijzigd, moet de high-availability-technologie worden gewijzigd in asynchrone modus, of moeten de netwerkbandbreedte en -snelheid tussen de principale en redundante databases worden verhoogd.

Overigens kan hetzelfde soort probleem optreden als het I/O-subsysteem zelf synchroon wordt gespiegeld - met een mogelijke vertraging voor alle schrijfbewerkingen die SQL Server uitvoert.

Samenvatting

Zoals u kunt zien, gaat de prestatie van transactielogboeken niet alleen over het genereren van extra transactielogboekrecords - er zijn ook veel omgevingsfactoren die ook een diepgaand effect kunnen hebben.

Waar het op neerkomt, is dat de gezondheid en prestaties van transactielogboeken van het grootste belang zijn voor het handhaven van de algehele werklastprestaties. In deze twee berichten heb ik de belangrijkste oorzaken van prestatieproblemen met transactielogboeken beschreven, zodat u hopelijk eventuele problemen kunt identificeren en verhelpen.

Als u veel meer wilt weten over transactielogboekbewerkingen en prestatieafstemming, raad ik u aan mijn 7,5 uur durende online training over logboekregistratie, herstel en het transactielogboek te bekijken, beschikbaar via Pluralsight.


  1. ASCII() Voorbeelden – MySQL

  2. De volgorde van tekens in een tekenreeks omkeren in MySQL

  3. Vergelijk alleen dag en maand met datumveld in mysql

  4. T-SQL Opgeslagen procedure overslaan: