sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man upptäcker och förhindrar oväntad tillväxt av SQL Server-databasen TempDB

Varje SQL Server-instans innehåller systemets SQL Server-databas som kallas TempDB. Det är typiskt för alla databasanslutningar, och nästan varje fråga använder sig av TempDB-databasen. Det är som ett hjärta för SQL Server-instansen. Praktiskt taget kan vi inte arbeta utan TempDB-databasen.

Låt oss ha en snabb sammanfattning av operationer där SQL Server använder TempDB.

  • Ordna efter och Gruppera efter klausul
  • Skapa index och återuppbygga index online
  • Templariska tabeller och tabellvariabler lagras i TempDB-databasen.
  • Isolering av ögonblicksbild och isolering av bekräftad ögonblicksbild
  • DBCC-kommandon
  • Hash sammanfogar statiska markörer, långvariga transaktioner.
  • XML-frågor
  • Interna objekt skapade av SQL Server-databasmotorn.
  • Versionsbutiker
  • Flera aktiva rekorduppsättningar (MARS)

Du kan läsa mer om TempDB i den här artikeln.

SQL Server återskapar denna TempDB-databas vid omstart av databasmotorns tjänst. Denna omstart kan bero på automatisk eller manuell omstart av SQL Service. Vi kan fråga sys.databases för att se TempDBs skapandedatum som också är en starttid för databastjänsten:

SELECT create_date AS 'SQL Service Startup Time'
FROM sys.databases
WHERE name = 'tempdb';

TempDB SQL Server-databaskonfigurationer och bästa praxis

Ibland märker vi oväntad tillväxt av TempDB-databasen. Det första steget för att undvika detta är att konfigurera det enligt bästa praxis. I det här avsnittet, låt oss se TempDB-konfigurationen är olika versioner av SQL Server.

Konfigurera TempDB för flera DATA-filer med jämn tillväxt

Enligt bästa praxis bör vi ha flera datafiler med jämn tillväxt av alla filer. Antalet filer beror på de logiska processorerna.

Processorer

Antal TempDB-datafiler

Logiska processorer mindre än eller lika med åtta

Åtta

Logiska processorer fler än åtta

Börja med åtta datafiler.

Öka datafilerna i multipel av fyra och övervaka prestandaräknare för TempDB-konflikt.

För SQL Server-versioner före 2016 har vi ingen konfiguration tillgänglig under installationsprocessen.

Som standard skapar den bara en data- och loggfil med följande konfigurationer:

TempDB Primär fil

Växa datafil automatiskt med tio procent (tills disken är full)

TempDB-loggfil

Automatisk utöka datafilen med tio procent (tills disken är full eller maximal loggfilstorlek når till 2 TB)

SQL Server 2014 TempDB SQL Server-databaskonfiguration

SQL Server 2016 ger förbättringar för TempDB-konfiguration under installationsprocessen enligt bästa praxis:

TempDB Primära och sekundära filer

Växa automatiskt med 64 MB (tills disken är full)

TempDB-loggfil

Växa automatiskt med 64 MB (tills disken är full eller maximal loggfilstorlek når 2 TB)

SQL Server 2016 och framåt TempDB-konfiguration

Ojämn automatisk tillväxt SQL Server-databas TempDB

SQL Server använder en round-robin-metod för att fylla flera datafiler om de inte har samma storlek. Ibland ser vi att en fil växer enormt, men andra filer förblir minimal tillväxt. I händelse av ojämna filer använder SQL Server den större filen för de flesta av frågorna, och den skulle fortsätta växa:

  1. Använd samma automatiska tillväxt av TempDB-filer (som diskuterades i föregående punkt).
  2. Aktivera spårningsflagga 1117 för att växa alla datafiler tillsammans i en databas.

Den andra punkten fixas automatiskt i SQL Server 2016 och framåt, men du bör aktivera den i tidigare versioner. Vi kräver inte denna spårningsflagga i SQL Server 2016 och högre.

TempDB-tillväxtscenarier

I det här avsnittet kommer vi att se några scenarier för SQL Server-databasens TempDB-tillväxt. I min SQL-instans har jag åtta datafiler med följande konfiguration:

Kör nu följande fråga för att skapa en tillfällig tabell och utföra datainfogning. Den temporära tabelllagringsplatsen är TempDB-databasen. Den här frågan använder en CROSS JOIN-operator med flera kolumner och sorterar resultaten ytterligare med hjälp av ORDER BY-satsen.

Obs! Kör inte den här frågan i produktionssystemet; Jag använder det endast i demosyfte.

SELECT *
FROM sys.configurations
CROSS JOIN sys.configurations SCA
CROSS JOIN sys.configurations SCB
CROSS JOIN sys.configurations SCC
CROSS JOIN sys.configurations SCD
CROSS JOIN sys.configurations SCE
CROSS JOIN sys.configurations SCF
CROSS JOIN sys.configurations SCG
CROSS JOIN sys.configurations SCH
ORDER BY SCA.name,
SCA.value,
SCC.value_in_use DESC;

Denna fråga kommer att ta lång tid och kan resultera i hög CPU-användning också i ditt system. Medan frågan körs öppnar du ett annat frågefönster och använder DMV sys.dm_db_task_space_usage för att få information om sidtilldelning och avallokeringsaktivitet per uppgift. Vi sammanfogar denna DMV med andra DMV:er för att få den nödvändiga informationen för SQL Server-databasen TempDB:

SELECT s.session_id, dbu.database_id
, dbu.internal_objects_alloc_page_count, dbu.internal_objects_dealloc_page_count
, (dbu.internal_objects_alloc_page_count - dbu.internal_objects_dealloc_page_count) * 8192 / 1024 kbytes_used_internal
, r.total_elapsed_time
FROM sys.dm_Exec_requests r
INNER JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
LEFT JOIN sys.dm_db_task_space_usage dbu ON dbu.session_id = r.session_id
AND dbu.request_id = r.request_id
WHERE internal_objects_alloc_page_count > 0
ORDER BY kbytes_used_internal DESC;
I utgången ser vi antalet interna objektsidor och deras storlekar (kbytes_used_internal) för sessions-ID 55. SQL Server-frågeoptimerare exekverar denna fråga i en parallell modell; därför kan vi se flera sessions-ID 71 i utgången:

Du kan också se den beräknade genomförandeplanen, och som visas nedan får vi två kostsamma operatörer:

  • Parallellism:47,3 %
  • Sortering:52,3 %

I sorteringsoperatören kan vi se hög uppskattad operatörskostnad 138 576,5:

Följande fråga använder DMV sys.dm_db_file_space_usage och sammanfogar den med sys.master_files för att kontrollera antalet tilldelade och oallokerade sidräkningar i SQL Server-databasen TempDB medan frågan körs:

select mf.physical_name, mf.size as entire_file_page_count,
dfsu.unallocated_extent_page_count,
dfsu.user_object_reserved_page_count,
dfsu.internal_object_reserved_page_count,
dfsu.mixed_extent_page_count
from sys.dm_db_file_space_usage dfsu
join sys.master_files as mf
on mf.database_id = dfsu.database_id
and mf.file_id = dfsu.file_id

Vi kan övervaka exekveringen av frågan, dess användning i TempDB-databasen och vid behov döda processen för att frigöra utrymmet omedelbart. Vi bör också optimera frågan vilket orsakar massiv TempDB-tillväxt.

Övervaka SQL Server-databas TempDB-användning med utökade händelser

Utökade händelser är användbara för TempDB-databasövervakning. Vi kan lägga till följande utökade händelser med hjälp av frågan:

  • database_file_size_change
  • databases_log_file_used_size_changed

Skapa utökad händelse

CREATE EVENT SESSION [TempDB Usage] ON SERVER
ADD EVENT sqlserver.database_file_size_change(

ACTION(sqlserver.client_hostname,sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text)),
ADD EVENT sqlserver.databases_log_file_used_size_changed(

ACTION(sqlserver.client_hostname,sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text))
ADD TARGET package0.event_file(SET filename=N'TempDBUsage',max_rollover_files=(0))
WITH (STARTUP_STATE=OFF)
GO

Starta utökad evenemangssession

ALTER EVENT SESSION [TempDBTest] ON SERVER STATE = START;

Kör nu din arbetsbelastning för att använda TempDB-databasen och utöka datafilerna. De utökade händelserna fångar datafiltillväxt och fråga som orsakade denna tillväxt.

Du kan antingen visa filen för utökad händelsesession i SSMS GUI-läge eller använda följande fråga för att övervaka TempDB-tillväxten.

Övervaka TempDB-tillväxt

SELECT [eventdata].[event_data].[value]('(event/action[@name="session_id"]/value)[1]', 'INT') AS [SessionID],
[eventdata].[event_data].[value]('(event/action[@name="client_hostname"]/value)[1]', 'VARCHAR(100)') AS [ClientHostName],
DB_NAME([eventdata].[event_data].[value]('(event/action[@name="database_id"]/value)[1]', 'BIGINT')) AS [GrowthDB],
[eventdata].[event_data].[value]('(event/data[@name="file_name"]/value)[1]', 'VARCHAR(200)') AS [GrowthFile],
[eventdata].[event_data].[value]('(event/data[@name="file_type"]/text)[1]', 'VARCHAR(200)') AS [DBFileType],
[eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(MAX)') AS [EventName],
[eventdata].[event_data].[value]('(event/data[@name="size_change_kb"]/value)[1]', 'BIGINT') AS [SizeChangedKb],
[eventdata].[event_data].[value]('(event/data[@name="total_size_kb"]/value)[1]', 'BIGINT') AS [TotalSizeKb],
[eventdata].[event_data].[value]('(event/data[@name="duration"]/value)[1]', 'BIGINT') AS [DurationInMS],
[eventdata].[event_data].[value]('(event/@timestamp)[1]', 'VARCHAR(MAX)') AS [GrowthTime],
[eventdata].[event_data].[value]('(event/action[@name="sql_text"]/value)[1]', 'VARCHAR(MAX)') AS [QueryText]
FROM
(
SELECT CAST([event_data] AS XML) AS [TargetData]
FROM [sys].[fn_xe_file_target_read_file]('C:\TEMP\TempDBusage*.xel', NULL, NULL, NULL)
) AS [eventdata]([event_data])
WHERE [eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(100)') = 'database_file_size_change'
OR [eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(100)') = 'databases_log_file_used_size_changed'
AND [eventdata].[event_data].[value]('(event/@name)[1]', 'VARCHAR(MAX)') <> 'databases_log_file_used_size_changed'
ORDER BY [GrowthTime] ASC;

Snapshot Isolation

Du kan använda ögonblicksbildsisolering för dina frågor. I denna isoleringsmodell lagrar SQL Server de uppdaterade radversionerna av varje transaktion i TempDB. I händelse av en stor eller långvarig transaktion kan du se en enorm TempDB-databas.

Du kan utföra transaktionen med kommandot SET och specificera ögonblicksbildsisolering:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRAN;
UPDATE [AdventureWorks].[Person].[Person]
SET
[Title] = 'Mr.';
COMMIT TRAN;

Du kan också fråga sys.databases systemvy för att kontrollera om någon användardatabas har ögonblicksbildsisolering.

Fråga för att aktivera ögonblicksbildsisolering i AdventureWorks-databasen

ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

Fråga för att kontrollera användardatabasen med ögonblicksbildsisolering

SELECT *
FROM sys.databases
WHERE(snapshot_isolation_state = 1
OR is_read_committed_snapshot_on = 1)
AND database_id > 4;

I följande skärmdump kan du se att AdventureWorks-databasen har ögonblicksbildsisolering. TempDB-databasen har också ögonblicksbildsisolering, men i frågan har vi hoppat över database_id mindre än 4:

Vi kan använda DMV sys.dm_db_file_space_usage för att övervaka versionslagret i TempDB:

SELECT GETDATE() AS runtime,
SUM(user_object_reserved_page_count) * 8 AS usr_obj_kb,
SUM(internal_object_reserved_page_count) * 8 AS internal_obj_kb,
SUM(version_store_reserved_page_count) * 8 AS version_store_kb,
SUM(unallocated_extent_page_count) * 8 AS freespace_kb,
SUM(mixed_extent_page_count) * 8 AS mixedextent_kb
FROM sys.dm_db_file_space_usage;

Här kan vi se versionsbutikens storlek är 67968 KB. För en stor eller långvarig transaktion kan du se en enorm SQL Server-databas TempDB-storlek på grund av detta versionslager:

Ett annat fall som kan orsaka en enorm storlek på versionslagret är Alltid på skrivskyddad sekundär replika. Om du kör någon fråga på den sekundära databasen, använder den automatiskt ögonblicksbildsisoleringsnivån. Som du vet kopierar isoleringsnivå för ögonblicksbilder radversionen i TempDB.

Du bör övervaka följande perfmonräknare:

  • SQLServer:Transaktioner\Longest Transaction Running Time – Den fångar den mest utvidgade aktiva transaktionen.
  • SQLServer:Transaktioner\Version Store Size (KB) – Den fångar den aktuella storleken på alla versionslagrar i TempDB.
  • SQLServer:Transaktioner\Versionsrensningshastighet (KB/s ) – Du kan använda den här räknaren för att visa hastigheten för versionsrensning i TempDB
  • SQLServer:Transaktioner\Versionsgenereringshastighet (KB/s) – Du kan fånga versionslagrets fångsthastighet med den här räknaren.

Du bör också övervaka TempDB-tillväxten för versionshanteringen i Always på den sekundära databasen. Döda de långvariga sessionerna så att den kan rensa versionshanteringen och återta utrymme i TempDB-databasen.

Slutsats

I den här artikeln lärde vi oss om SQL Server-databasen TempDB-databas bästa praxis och olika metoder för att upptäcka, förhindra oväntad tillväxt. Du bör övervaka TempDB regelbundet och konfigurera olika varningar så att de är proaktiva.

  • TempDB-storleksövervakning
  • Övervakning av Drive-utrymme
  • Långa transaktioner


  1. Lyssna på Microsoft Access Podcast avsnitt 1

  2. Förbättra vår onlinejobbportaldatamodell

  3. Multi-Cloud Full Databas Cluster Failover-alternativ för PostgreSQL

  4. Optimera Postgres tidsstämpel frågeintervall