Lead
tempdb to nie kosz na śmieci ani magiczny bufor, który „sam się ogarnia”. Jeśli rośnie – to dlatego, że Twoje zapytania, sortowania, spule i wersjonowanie transakcji potrzebują miejsca. Tu masz praktyczny runbook bez mitów.
TL;DR
- Zdiagnozuj dlaczego rośnie (
version store, rehash w hash joinach, spill do tempdb). - Usuń przyczynę (plany, indeksy, hinty, rozmiary pamięci).
- Dopiero na końcu — shrink z restartem usługi lub
DBCC SHRINKFILE + ALTER DATABASE tempdb MODIFY FILE.
Diagnoza: co zżera tempdb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| -- 1) Tabela wersji (Snapshot Isolation/ADR)
SELECT TOP(10) database_id, total_version_store_reserved_page_count*8/1024 AS MB
FROM sys.dm_tran_version_store_space_usage
ORDER BY 2 DESC;
-- 2) Najwięksi alokujący
SELECT TOP(20)
t.session_id, t.request_id, t.task_alloc*8/1024 AS MB_alloc, t.task_dealloc*8/1024 AS MB_dealloc,
s.login_name, r.command, r.status, r.wait_type, r.cpu_time, r.total_elapsed_time
FROM (
SELECT session_id, request_id,
SUM(internal_objects_alloc_page_count + user_objects_alloc_page_count) AS task_alloc,
SUM(internal_objects_dealloc_page_count + user_objects_dealloc_page_count) AS task_dealloc
FROM sys.dm_db_task_space_usage
GROUP BY session_id, request_id) AS t
LEFT JOIN sys.dm_exec_sessions s ON s.session_id=t.session_id
LEFT JOIN sys.dm_exec_requests r ON r.session_id=t.session_id AND r.request_id=t.request_id
ORDER BY MB_alloc DESC;
|
Klasyka błędów
- Nieustanny spill przez brak indeksu lub zbyt mało pamięci w grantach.
- Uruchomione
READ_COMMITTED_SNAPSHOT + długie transakcje → wersje nie są zbierane. - Potężne sortowania/
HASH MATCH na kolumnach NVARCHAR(MAX)/VARBINARY(MAX).
Kiedy i jak shrinkować
- Po usunięciu przyczyny. Inaczej wróci jak bumerang.
- tempdb resetuje się przy starcie usługi. Najczystszy shrink to okno serwisowe + restart SQL Server.
Procedura bez restartu
1
2
3
4
5
6
7
| USE master;
-- 1) Przenieś tempdb do docelowego rozmiaru i plików
ALTER DATABASE tempdb MODIFY FILE (NAME = tempdev, SIZE = 8192MB, FILEGROWTH = 256MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = templog, SIZE = 2048MB, FILEGROWTH = 256MB);
-- 2) Przytnij pliki (powtarzaj do skutku, obserwuj sys.dm_db_file_space_usage)
DBCC SHRINKFILE (tempdev, 8192);
DBCC SHRINKFILE (templog, 2048);
|
Wiele mniejszych plików danych (po 1 na 4 rdzenie, max 8) pomaga z latchami PFS/GAM/SGAM.
1
2
| -- Dodanie plików (przykład)
ALTER DATABASE tempdb ADD FILE (NAME = tempdev2, FILENAME='T:\tempdb\tempdb2.ndf', SIZE=8192MB, FILEGROWTH=256MB);
|
Weryfikacja
sys.dm_db_file_space_usage – wolne vs użyte.- Brak aktywnego version store (lub w normie).
- W Grafanie: spadek
tempdb used space, brak długich spillów w Query Store.
Checklista „done”