Under det senaste året har jag bloggat flera gånger på SQLPerformance.com om transaktionsloggprestandaproblem (se här) och jag lovade att diskutera transaktionsloggövervakning, vilket jag kommer att göra i det här inlägget. Jag kommer att presentera några av de mätvärden du kan spåra, varför du bör bry dig och alla råd för att hantera det angivna problemet.
DMVs
Det enklaste sättet att övervaka transaktionslogg I/O-latenser är att använda sys.dm_io_virtual_file_stats
DMV. Du måste utföra lite matematik för att få användbara resultat och du kan få lite exempelkod i VirtualFileStats.sql-skriptet i denna demo-zip-fil. Du vill verkligen se skrivfördröjningar på mindre än 5ms för transaktionsloggen.
Tidigare i november bloggade jag resultaten av en undersökning som visade transaktionslogg- och tempdb-datafilfördröjningar för mer än 25 000 databaser runt om i världen (se här), där 80 % av databaserna når 5ms eller mindre för skrivfördröjning för transaktionsloggar.
Om din skrivfördröjning är högre än 5ms kan du:
- Arbeta för att minska mängden logg som genereras och/eller mängden loggspolningar från små transaktioner, som jag beskrev i tidigare inlägg.
- Följ några av felsökningsstegen som jag beskriver i undersökningens blogginlägg ovan.
- Flytta till ett snabbare I/O-undersystem och kom ihåg att om du bestämmer dig för att använda en SSD måste du använda två i en RAID-1-konfiguration.
En annan sak du kan är att se till att se till att du inte når den hårda gränsen på 32 utestående skriv-I/O för varje databas transaktionslogg i 2008 R2 och tidigare (höjt till 2012 från SQL Server 2012 och framåt). Du kan försöka göra detta genom att titta på den fysiska disken/Avg. Diskskrivkölängd, men det är för en hel volym, inte per fil, så om det finns något annat på volymen förutom loggfilen du är intresserad av, kommer det inte att ge dig ett giltigt nummer. Ett bättre sätt är att sammanställa resultaten av sys.dm_io_pending_io_requests
DMV, som listar alla utestående I/O. Här är lite kod för att göra det:
SELECT COUNT (*) AS [PendingIOs], DB_NAME ([vfs].[database_id]) AS [DBName], [mf].[name] AS [FileName], [mf].[type_desc] AS [FileType], SUM ([pior].[io_pending_ms_ticks]) AS [TotalStall] FROM sys.dm_io_pending_io_requests AS [pior] JOIN sys.dm_io_virtual_file_stats (NULL, NULL) AS [vfs] ON [vfs].[file_handle] = [pior].[io_handle] JOIN sys.master_files AS [mf] ON [mf].[database_id] = [vfs].[database_id] AND [mf].[file_id] = [vfs].[file_id] WHERE [pior].[io_pending] = 1 GROUP BY [vfs].[database_id], [mf].[name], [mf].[type_desc] ORDER BY [vfs].[database_id], [mf].[name];
Du kan enkelt ändra detta till att endast visa resultat för loggfiler (filtrera på type_desc ='LOG'
) och bara för det databas-ID du är intresserad av.
Om du upptäcker att du når gränsen på 32 för en viss databas kan du:
- Minska mängden loggrensningar som sker genom att minska antalet små transaktioner och se upp för saker som siddelningar och oanvända/dubbletter av index som ändras under datamodifieringsoperationer. Du kan läsa mer om att optimera loggspolningar i det här blogginlägget
- Försök att använda ett snabbare I/O-undersystem
- Uppgradera till SQL Server 2012 eller högre, där gränsen är 112
- Prova funktionen
delayed durability feature
DMV som lades till i SQL Server 2014 - Som en sista utväg, dela arbetsbelastningen över flera databaser eller servrar
Om du är intresserad av att se hur mycket transaktionslogg som genereras av dina transaktioner kan du använda sys.dm_tran_database_transactions
DMV, i kod som liknar den nedan:
BEGIN TRAN; GO -- Do something you want to evaluate GO SELECT [database_transaction_log_bytes_used] FROM sys.dm_tran_database_transactions WHERE [database_id] = DB_ID (N'YourTestDB'); GO
Du kan bli mycket förvånad över hur mycket logg som genereras, speciellt i tempdb för kod som använder temporära objekt. Och naturligtvis kan tempdbs transaktionslogg vara en flaskhals precis som för en användardatabas.
Räknare för prestandaövervakning
De loggrelaterade prestandaräknare finns alla i databasprestandaobjektet. Här är några av de viktigaste att titta på (antingen med själva Performance Monitor eller med SQL Agent-varningar eller med sys.dm_os_performance_counters DMV eller i ditt favoritverktyg för övervakning från tredje part):
Tloggtillväxt
Du vill inte se denna räknare öka eftersom det säger att det händer något i databasen som gör att mer transaktionslogg genereras än vad det finns aktuellt utrymme. Det innebär att transaktionsloggen inte kan renas så du bör undersöka orsaken genom att fråga log_reuse_wait_desc-fältet i sys.databases och vidta alla åtgärder som krävs (se Books Online-ämnet Faktorer som kan försena loggavkortning för mer information). Något exempel på kod skulle vara:
SELECT [log_reuse_wait_desc] FROM sys.databases WHERE [name] = N'YourDB'; GO
Närhelst en loggtillväxt inträffar måste den nyligen allokerade delen av transaktionsloggen nollställas, plus att fler virtuella loggfiler läggs till – båda kan orsaka problem som jag bloggade om tidigare.
Logg krymper
Såvida du inte är den person som utför krympningsoperationen för att få tillbaka en transaktionslogg som är utom kontroll, vill du inte se denna räknare öka. Om någon bara krymper transaktionsloggen utan goda skäl kommer den troligen att växa igen, vilket orsakar problem som jag bloggade om tidigare.
Procent logg använd
Du bör övervaka denna räknare och vara orolig om värdet blir högre än 90 %, eftersom det indikerar att en loggtillväxt kan vara nära förestående och transaktionsloggen inte kan rensas korrekt, som jag diskuterade ovan.
Loggspolning väntar/sek
Du vill att detta värde ska förbli detsamma eller minska. Om det ökar betyder det att du har en flaskhals i I/O-undersystemet eller en flaskhals inuti stockspolmekanismen eftersom du spolar många små delar av stocken. En ökning här kan också korrelera med att träffa de 32 utestående I/O:erna för loggen. Se diskussionen om sys.dm_io_pending_io_requests
ovan för mer information.
Loggbytes tömda/sek och logg tömningar/sek
Dessa två räknare låter dig räkna ut den genomsnittliga stockspolstorleken genom att dividera den första räknaren med den andra. Resultatet blir ett värde mellan 512 och 61440 (minsta respektive maximala storlek för en stockspolning). Ett lägre värde är mer sannolikt att korrelera med ökande Log Flush Waits/sek. Återigen, se diskussionen om sys.dm_io_pending_io_requests
ovan för mer information.
Utökade evenemang
För de mer avancerade bland er finns det några utökade evenemang som du kan använda för att se vad som händer med loggen. Jag rekommenderar att du börjar med att använda IO-spårningsmallen för databasloggfil i SQL Server 2012 SSMS. Du kan komma till detta genom att gå till Objektutforskaren och sedan din instans -> Hantering -> Utökade händelser och högerklicka på Sessioner för att välja New Session Wizard. I fönstret som kommer upp skriver du ett sessionsnamn och väljer spårningsmallen från rullgardinsmenyn. Tryck sedan på Ctrl+Skift+N och sessionen kommer att skriptas till ett frågefönster. Detaljerna för allt där inne ligger tyvärr utanför det här inläggets räckvidd, men mallbeskrivningen är ganska förklarande:
Denna mall övervakar IO för databasloggfiler på en server genom att spåra asynkron IO, databasloggspolningar, filskrivningar, spinlock-backoffs av typen LOGFLUSHQ och väntar av typen WRITELOG. Denna mall samlar in data på två sätt:rådata samlas in till en ringbuffert och spinlock backoff-information aggregeras baserat på indatabufferten (sql_text). Sessionen filtreras för en enda loggfil per databas; om du har flera loggfiler kan du ändra filtret för händelserna file_write_completed och file_written för att inkludera mer än bara file_id =2.Det finns också en ny utökad händelse i SQL Server 2012 som heter transaktionslogg som kan användas för att göra alla möjliga intressanta analyser av vilka loggposter som genereras. Det är definitivt ett ämne jag kommer att ta upp i ett framtida inlägg.
Sammanfattning
Med tanke på all information ovan borde du kunna komma med ett ganska bra övervakningssystem för transaktionsloggar. Transaktionsloggens hälsa är av största vikt för att säkerställa att din arbetsbelastning fungerar som den ska och jag hoppas att de fyra inläggen i den här serien (plus alla andra länkar) har hjälpt dig att förbättra den övergripande prestandan för din SQL Server-miljö.