Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

So erkennen und verhindern Sie unerwartetes Wachstum der SQL Server-Datenbank TempDB

Jede SQL Server-Instanz enthält die System-SQL Server-Datenbank namens TempDB. Es ist typisch für alle Datenbankverbindungen, und fast jede Abfrage nutzt die TempDB-Datenbank. Es ist wie ein Herz für die SQL Server-Instanz. Ohne die TempDB-Datenbank können wir praktisch nicht arbeiten.

Lassen Sie uns kurz die Operationen zusammenfassen, bei denen SQL Server TempDB verwendet.

  • Order by- und Group by-Klausel
  • Indexerstellung und Online-Indexneuaufbau
  • Die Speicherung temporärer Tabellen und Tabellenvariablen erfolgt in der TempDB-Datenbank.
  • Snapshot-Isolierung und Snapshot-Isolierung mit Lesebestätigung
  • DBCC-Befehle
  • Hash verbindet statische Cursor, Transaktionen mit langer Laufzeit.
  • XML-Abfragen
  • Interne Objekte, die von der SQL Server-Datenbank-Engine erstellt wurden.
  • Versionsspeicher
  • Mehrere aktive Datensätze (MARS)

Weitere Informationen zu TempDB finden Sie in diesem Artikel.

SQL Server erstellt diese TempDB-Datenbank beim Neustart des Datenbankmoduldiensts neu. Dieser Neustart kann auf den automatischen oder manuellen Neustart des SQL-Diensts zurückzuführen sein. Wir können sys.databases abfragen, um das Erstellungsdatum von TempDB anzuzeigen, das auch eine Startzeit des Datenbankdienstes ist:

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

TempDB SQL Server-Datenbankkonfigurationen und Best Practices

Manchmal bemerken wir ein unerwartetes Wachstum der TempDB-Datenbank. Der erste Schritt, um dies zu vermeiden, besteht darin, es gemäß den Best Practices zu konfigurieren. Sehen wir uns in diesem Abschnitt die TempDB-Konfiguration in verschiedenen Versionen von SQL Server an.

TempDB für mehrere DATA-Dateien mit gleichmäßigem Wachstum konfigurieren

Gemäß Best Practice sollten wir mehrere Datendateien mit gleichmäßigem Wachstum aller Dateien haben. Die Anzahl der Dateien hängt von den logischen Prozessoren ab.

Prozessoren

Anzahl der TempDB-Datendateien

Logische Prozessoren kleiner oder gleich acht

Acht

Logische Prozessoren größer als acht

Beginnen Sie mit acht Datendateien.

Erhöhen Sie die Datendateien um ein Vielfaches von vier und überwachen Sie die Leistungsindikatoren auf TempDB-Konflikte.

Für SQL Server-Versionen vor 2016 steht während des Installationsvorgangs keine Konfiguration zur Verfügung.

Standardmäßig erstellt es nur eine Daten- und Protokolldatei mit den folgenden Konfigurationen:

TempDB-Primärdatei

Datendatei automatisch um zehn Prozent vergrößern (bis die Festplatte voll ist)

TempDB-Protokolldatei

Datendatei automatisch um zehn Prozent vergrößern (bis die Festplatte voll ist oder die maximale Größe der Protokolldatei 2 TB erreicht)

SQL Server 2014 TempDB SQL Server-Datenbankkonfiguration

SQL Server 2016 bietet Verbesserungen für die TempDB-Konfiguration während des Installationsprozesses gemäß den Best Practices:

Primäre und sekundäre TempDB-Dateien

Automatisch um 64 MB vergrößern (bis die Festplatte voll ist)

TempDB-Protokolldatei

Automatisch um 64 MB vergrößern (bis die Festplatte voll ist oder die maximale Größe der Protokolldatei 2 TB erreicht)

TempDB-Konfiguration für SQL Server 2016 und höher

Ungleichmäßiges automatisches Wachstum der SQL Server-Datenbank TempDB

SQL Server verwendet eine Round-Robin-Methode, um mehrere Datendateien zu füllen, wenn sie nicht dieselbe Größe haben. Manchmal sehen wir, dass eine Datei sehr groß wird, aber andere Dateien minimal wachsen. Bei ungleichmäßigen Dateien verwendet SQL Server die größere Datei für die meisten Abfragen, und sie würde weiter wachsen:

  1. Verwenden Sie dasselbe automatische Wachstum von TempDB-Dateien (wie im vorherigen Punkt besprochen).
  2. Aktivieren Sie das Trace-Flag 1117, um alle Datendateien in einer Datenbank zusammenzufassen.

Der zweite Punkt wird ab SQL Server 2016 automatisch behoben, Sie sollten ihn jedoch in früheren Versionen aktivieren. Wir benötigen dieses Trace-Flag in SQL Server 2016 und höher nicht.

TempDB-Wachstumsszenarien

In diesem Abschnitt sehen wir einige Szenarien für das TempDB-Wachstum der SQL Server-Datenbank. In meiner SQL-Instanz habe ich acht Datendateien mit der folgenden Konfiguration:

Führen Sie nun die folgende Abfrage aus, um eine temporäre Tabelle zu erstellen und Daten einzufügen. Der temporäre Tabellenspeicherort ist die TempDB-Datenbank. Diese Abfrage verwendet einen CROSS JOIN-Operator mit mehreren Spalten und sortiert die Ergebnisse mithilfe der ORDER BY-Klausel weiter.

Hinweis: Führen Sie diese Abfrage nicht im Produktionssystem aus; Ich verwende es nur zu Demozwecken.

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;

Diese Abfrage dauert lange und kann auch in Ihrem System zu einer hohen CPU-Auslastung führen. Öffnen Sie während der Ausführung der Abfrage ein weiteres Abfragefenster und verwenden Sie die DMV sys.dm_db_task_space_usage, um Informationen von abzurufen Seitenzuweisungs- und Freigabeaktivität durch die Aufgabe. Wir führen diese DMV mit anderen DMVs zusammen, um die erforderlichen Informationen für die SQL Server-Datenbank TempDB zu erhalten:

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;
In der Ausgabe sehen wir die Anzahl der internen Objektseiten und deren Größe (kbytes_used_internal) für die Sitzungs-ID 55. SQL Server-Abfrageoptimierer, der diese Abfrage in einem parallelen Modell ausführt; Daher können wir in der Ausgabe die Mehrfachsitzungs-ID 71 sehen:

Sie können auch den geschätzten Ausführungsplan anzeigen, und wie unten gezeigt, erhalten wir zwei kostspielige Operatoren:

  • Parallelität:47,3 %
  • Sortierung:52,3 %

Im Sort-Operator sehen wir hohe geschätzte Operatorkosten von 138.576,5:

Die folgende Abfrage verwendet DMV sys.dm_db_file_space_usage und verbindet es mit sys.master_files, um die Anzahl der zugewiesenen und nicht zugewiesenen Extent-Seiten in der TempDB der SQL Server-Datenbank zu überprüfen, während die Abfrage ausgeführt wird:

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

Wir können die Abfrageausführung und ihre Verwendung in der TempDB-Datenbank überwachen und bei Bedarf den Prozess beenden, um den Speicherplatz sofort freizugeben. Wir sollten auch die Abfrage optimieren, die ein massives TempDB-Wachstum verursacht.

Überwachen Sie die TempDB-Nutzung der SQL Server-Datenbank mithilfe erweiterter Ereignisse

Erweiterte Ereignisse sind nützlich für die Überwachung der TempDB-Datenbank. Wir können die folgenden erweiterten Ereignisse mit der Abfrage hinzufügen:

  • database_file_size_change
  • databases_log_file_used_size_changed

Erweitertes Ereignis erstellen

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

Erweiterte Ereignissitzung starten

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

Führen Sie nun Ihre Workload aus, um die TempDB-Datenbank zu verwenden und die Datendateien zu vergrößern. Die erweiterten Ereignisse erfassen das Wachstum von Datendateien und Abfragen, die dieses Wachstum verursacht haben.

Sie können die erweiterte Ereignissitzungsdatei entweder im SSMS-GUI-Modus anzeigen oder die folgende Abfrage verwenden, um das TempDB-Wachstum zu überwachen.

TempDB-Wachstum überwachen

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-Isolierung

Sie können Snapshot-Isolation für Ihre Abfragen verwenden. In diesem Isolationsmodell speichert SQL Server die aktualisierten Zeilenversionen jeder Transaktion in der TempDB. Im Falle einer großen oder lang andauernden Transaktion können Sie eine riesige TempDB-Datenbank sehen.

Sie können die Transaktion mit dem SET-Befehl ausführen und die Snapshot-Isolation angeben:

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

Sie können auch sys.databases abfragen Systemansicht, um zu überprüfen, ob eine Benutzerdatenbank über eine Snapshot-Isolation verfügt.

Abfrage zum Aktivieren der Snapshot-Isolation in der AdventureWorks-Datenbank

ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

Abfrage zum Überprüfen der Benutzerdatenbank mit Snapshot-Isolation

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

Im folgenden Screenshot sehen Sie, dass die AdventureWorks-Datenbank über eine Snapshot-Isolation verfügt. Die TempDB-Datenbank verfügt auch über eine Snapshot-Isolation, aber in der Abfrage haben wir database_id kleiner als 4:

übersprungen

Wir können DMV sys.dm_db_file_space_usage verwenden, um den Versionsspeicher in der TempDB zu überwachen:

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;

Hier können wir sehen, dass die Größe des Versionsspeichers 67968 KB beträgt. Bei einer großen oder lang andauernden Transaktion können Sie aufgrund dieses Versionsspeichers eine enorme TempDB-Größe der SQL Server-Datenbank sehen:

Ein weiterer Fall, der zu einer enormen Größe des Versionsspeichers führen kann, ist Always on Read-only Secondary Replica. Wenn Sie eine Abfrage in der sekundären Datenbank ausführen, verwendet diese automatisch die Snapshot-Isolationsstufe. Wie Sie wissen, kopiert die Snapshot-Isolationsstufe die Zeilenversion in der TempDB.

Sie sollten die folgenden Leistungsindikatoren überwachen:

  • SQLServer:Transaktionen\Längste Transaktionslaufzeit – Es erfasst die längste aktive Transaktion.
  • SQLServer:Transactions\Version Store Size (KB) – Es erfasst die aktuelle Größe aller Versionsspeicher in TempDB.
  • SQLServer:Transaktions-\Versions-Bereinigungsrate (KB/s ) – Sie können diesen Zähler verwenden, um die Rate der Versionsbereinigung in TempDB anzuzeigen
  • SQLServer:Transaktionen\Versionsgenerierungsrate (KB/s) – Mit diesem Zähler können Sie die Erfassungsrate des Versionsspeichers erfassen.

Sie sollten das TempDB-Wachstum für die Versionsverwaltung in Always auch in der sekundären Datenbank überwachen. Beenden Sie die lange laufenden Sitzungen, damit die Versionierung gelöscht und Speicherplatz in der TempDB-Datenbank zurückgewonnen werden kann.

Schlussfolgerung

In diesem Artikel haben wir die Best Practices für die SQL Server-Datenbank TempDB und verschiedene Methoden zum Erkennen und Verhindern von unerwartetem Wachstum kennengelernt. Sie sollten TempDB regelmäßig überwachen und verschiedene Warnungen konfigurieren, um proaktiv zu sein.

  • Überwachung der TempDB-Größe
  • Speicherplatzüberwachung
  • Langfristige Transaktionen