Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak wykryć i zapobiec nieoczekiwanemu wzrostowi bazy danych SQL Server TempDB

Każda instancja SQL Server zawiera systemową bazę danych SQL Server o nazwie TempDB. Jest to typowe dla wszystkich połączeń z bazą danych, a prawie każde zapytanie korzysta z bazy danych TempDB. Jest jak serce dla instancji SQL Server. Praktycznie nie możemy pracować bez bazy danych TempDB.

Zróbmy krótkie podsumowanie operacji, w których SQL Server korzysta z bazy danych TempDB.

  • Zamów według i Grupuj według klauzuli
  • Tworzenie indeksu i przebudowywanie indeksu online
  • Przechowywanie tabel temp i zmiennych tabel znajduje się w bazie danych TempDB.
  • Izolacja migawki i odczytanie izolacji migawki zatwierdzonej
  • polecenia DBCC
  • Hash łączy statyczne kursory, długotrwałe transakcje.
  • Zapytania XML
  • Wewnętrzne obiekty utworzone przez silnik bazy danych SQL Server.
  • Sklepy z wersjami
  • Wiele aktywnych zestawów rekordów (MARS)

Możesz przeczytać więcej o TempDB w tym artykule.

SQL Server odtwarza tę bazę danych TempDB po ponownym uruchomieniu usługi aparatu bazy danych. To ponowne uruchomienie może być spowodowane automatycznym lub ręcznym ponownym uruchomieniem usługi SQL. Możemy zapytać sys.databases, aby wyświetlić datę utworzenia TempDB, która jest również czasem uruchomienia usługi bazy danych:

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

Konfiguracje bazy danych TempDB SQL Server i najlepsze praktyki

Czasami zauważamy nieoczekiwany wzrost bazy danych TempDB. Pierwszym krokiem do uniknięcia tego jest skonfigurowanie go zgodnie z najlepszymi praktykami. W tej sekcji przyjrzyjmy się, że konfiguracja TempDB to różne wersje SQL Server.

Konfiguruj TempDB dla wielu plików DANYCH z równomiernym wzrostem

Zgodnie z najlepszymi praktykami powinniśmy mieć wiele plików danych z równomiernym wzrostem wszystkich plików. Liczba plików zależy od procesorów logicznych.

Procesory

Liczba plików danych TempDB

Procesory logiczne mniejsze lub równe ośmiu

Osiem

Procesory logiczne większe niż osiem

Zacznij od ośmiu plików danych.

Zwiększ liczbę plików danych o wielokrotność czterech i monitoruj liczniki wydajności pod kątem rywalizacji o TempDB.

W przypadku wersji programu SQL Server sprzed 2016 r. nie mamy konfiguracji dostępnej podczas procesu instalacji.

Domyślnie tworzy tylko jeden plik danych i dziennika o następujących konfiguracjach:

Plik podstawowy bazy danych TempDB

Automatycznie powiększaj plik danych o dziesięć procent (do zapełnienia dysku)

Plik dziennika TempDB

Automatycznie powiększaj plik danych o dziesięć procent (do momentu zapełnienia dysku lub maksymalnego rozmiaru pliku dziennika do 2 TB)

Konfiguracja bazy danych SQL Server 2014 TempDB SQL Server

SQL Server 2016 zapewnia ulepszenia konfiguracji TempDB podczas procesu instalacji zgodnie z najlepszymi praktykami:

TempDB Pliki podstawowe i dodatkowe

Automatycznie powiększaj o 64 MB (do zapełnienia dysku)

Plik dziennika TempDB

Automatycznie powiększaj o 64 MB (do zapełnienia dysku lub maksymalnego rozmiaru pliku dziennika do 2 TB)

Konfiguracja serwera SQL Server 2016 i nowszej bazy danych

Nierównomierny automatyczny wzrost bazy danych SQL Server TempDB

SQL Server używa metody round-robin do wypełniania wielu plików danych, jeśli nie mają tego samego rozmiaru. Czasami widzimy, że jeden plik rośnie ogromnie, ale inne pliki pozostają minimalnym wzrostem. W przypadku nierównych plików SQL Server używa większego pliku dla większości zapytań i będzie on nadal rósł:

  1. Użyj tego samego automatycznego wzrostu plików TempDB (jak omówiono w poprzednim punkcie).
  2. Włącz flagę śledzenia 1117 do powiększania wszystkich plików danych w bazie danych.

Drugi punkt jest ustalany automatycznie w SQL Server 2016 i nowszych, jednak należy go włączyć we wcześniejszych wersjach. Ta flaga śledzenia nie jest wymagana w SQL Server 2016 i nowszych.

Scenariusze wzrostu TempDB

W tej sekcji zobaczymy kilka scenariuszy wzrostu bazy danych SQL Server TempDB. W mojej instancji SQL mam osiem plików danych o następującej konfiguracji:

Teraz wykonaj następujące zapytanie, aby utworzyć tabelę tymczasową i wykonać wstawianie danych. Tymczasową lokalizacją przechowywania tabel jest baza danych TempDB. To zapytanie używa operatora CROSS JOIN z wieloma kolumnami i dodatkowo sortuje wyniki za pomocą klauzuli ORDER BY.

Uwaga: Nie uruchamiaj tego zapytania w systemie produkcyjnym; Używam go tylko do celów demonstracyjnych.

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;

To zapytanie zajmie dużo czasu i może spowodować duże użycie procesora w twoim systemie. Gdy zapytanie jest uruchomione, otwórz inne okno zapytania i użyj DMV sys.dm_db_task_space_usage, aby uzyskać informacje o alokacja stron i aktywność dealokacji według zadania. Łączymy ten DMV z innymi DMV, aby uzyskać wymagane informacje dla bazy danych SQL Server 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;
Na wyjściu widzimy wewnętrzne liczniki stron obiektów i ich rozmiary (kbytes_used_internal) dla identyfikatora sesji 55. Optymalizator zapytań SQL Server wykonujący to zapytanie w modelu równoległym; dlatego w danych wyjściowych możemy zobaczyć wielokrotny identyfikator sesji 71:

Możesz również zobaczyć szacunkowy plan wykonania i jak pokazano poniżej, otrzymujemy dwóch kosztownych operatorów:

  • Równoległość:47,3%
  • Sortuj:52,3%

W operatorze sortowania widzimy wysoki szacowany koszt operatora 138 576,5:

Poniższe zapytanie używa DMV sys.dm_db_file_space_usage i łączy go z sys.master_files, aby sprawdzić liczbę przydzielonych i nieprzydzielonych stron ekstentu w bazie danych SQL Server TempDB podczas wykonywania zapytania:

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

Możemy monitorować wykonanie zapytania, jego wykorzystanie w bazie danych TempDB i w razie potrzeby zakończyć proces, aby natychmiast zwolnić miejsce. Powinniśmy również zoptymalizować zapytanie, powodując ogromny wzrost TempDB.

Monitoruj użycie bazy danych SQL Server TempDB za pomocą rozszerzonych zdarzeń

Zdarzenia rozszerzone są przydatne do monitorowania bazy danych TempDB. Za pomocą zapytania możemy dodać następujące zdarzenia rozszerzone:

  • database_file_size_change
  • databases_log_file_used_size_changed

Utwórz rozszerzone wydarzenie

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

Rozpocznij rozszerzoną sesję wydarzenia

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

Teraz wykonaj obciążenie, aby korzystać z bazy danych TempDB i powiększać pliki danych. Zdarzenia rozszerzone rejestrują wzrost pliku danych i zapytania, które spowodowały ten wzrost.

Możesz wyświetlić plik rozszerzonej sesji zdarzeń w trybie SSMS GUI lub użyć następującego zapytania do monitorowania wzrostu bazy danych TempDB.

Monitoruj wzrost TempDB

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;

Izolacja migawki

Możesz użyć izolacji migawki dla zapytań. W tym modelu izolacji SQL Server przechowuje zaktualizowane wersje wierszy każdej transakcji w bazie danych TempDB. W przypadku dużej lub długotrwałej transakcji możesz zobaczyć ogromną bazę danych TempDB.

Możesz wykonać transakcję za pomocą polecenia SET i określić izolację migawki:

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

Możesz także wysłać zapytanie do sys.databases widok systemu, aby sprawdzić, czy jakakolwiek baza danych użytkownika ma izolację migawki.

Zapytanie, aby włączyć izolację migawek w bazie danych AdventureWorks

ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

Zapytanie o sprawdzenie bazy danych użytkowników z izolacją migawki

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

Na poniższym zrzucie ekranu widać, że baza danych AdventureWorks ma izolację migawek. Baza danych TempDB ma również izolację migawek, ale w zapytaniu pominęliśmy database_id mniejszy niż 4:

Możemy użyć DMV sys.dm_db_file_space_usage do monitorowania magazynu wersji w 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;

Tutaj widzimy, że rozmiar magazynu wersji wynosi 67968 KB. W przypadku dużej lub długotrwałej transakcji można zobaczyć ogromny rozmiar bazy danych SQL Server TempDB ze względu na ten magazyn wersji:

Innym przypadkiem, który może spowodować ogromny rozmiar magazynu wersji, jest zawsze w trybie tylko do odczytu replika pomocnicza. Jeśli wykonasz dowolne zapytanie w pomocniczej bazie danych, automatycznie użyje ona poziomu izolacji migawki. Jak wiadomo, poziom izolacji migawki kopiuje wersję wiersza w bazie danych TempDB.

Powinieneś monitorować następujące liczniki perfmon:

  • SQLServer:Transactions\Najdłuższy czas wykonywania transakcji – Przechwytuje najbardziej rozszerzoną aktywną transakcję.
  • SQLServer:Transakcje\Rozmiar magazynu wersji (KB) – Przechwytuje aktualny rozmiar wszystkich wersji przechowywanych w TempDB.
  • SQLServer:Transakcje\Szybkość czyszczenia wersji (KB/s ) – Możesz użyć tego licznika, aby pokazać szybkość czyszczenia wersji w TempDB
  • SQLServer:Transakcje\Szybkość generowania wersji (KB/s) – Za pomocą tego licznika możesz przechwycić szybkość przechwytywania magazynu wersji.

Należy również monitorować wzrost TempDB pod kątem przechowywania wersji w Zawsze w pomocniczej bazie danych. Zabij długotrwałe sesje, aby można było wyczyścić wersjonowanie i odzyskać miejsce w bazie danych TempDB.

Wniosek

W tym artykule dowiedzieliśmy się o najlepszych praktykach bazy danych SQL Server w bazie danych TempDB i różnych metodach wykrywania i zapobiegania nieoczekiwanemu wzrostowi. Powinieneś regularnie monitorować TempDB i konfigurować różne alerty, aby były proaktywne.

  • Monitorowanie rozmiaru TempDB
  • Monitorowanie miejsca na dysku
  • Długotrwałe transakcje


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rozważania dotyczące bezpieczeństwa SQL Server

  2. TDS Server — używaj instrukcji Transact-SQL (T-SQL) do pracy z danymi Salesforce w SQL Server

  3. 4 wskazówki dotyczące uruchamiania diagnostyki SQL Server

  4. SYSDATETIMEOFFSET() Przykłady w SQL Server (T-SQL)

  5. Wyświetl listę kont skojarzonych z profilem poczty bazy danych w SQL Server