sql >> Databáze >  >> RDS >> Sqlserver

Jak zjistit a zabránit neočekávanému nárůstu SQL Server databáze TempDB

Každá instance SQL Server obsahuje systémovou databázi SQL Server s názvem TempDB. Je to typické pro všechna databázová připojení a téměř každý dotaz využívá databázi TempDB. Je to jako srdce pro instanci SQL Server. Bez databáze TempDB se prakticky neobejdeme.

Pojďme si rychle shrnout operace, ve kterých SQL Server používá TempDB.

  • Seřadit podle a seskupit podle klauzule
  • Vytvoření indexu a nové sestavení indexu online
  • Ukládání tabulek Temp a proměnných tabulek je v databázi TempDB.
  • Izolace snímku a izolace potvrzeného snímku čtení
  • Příkazy DBCC
  • Hash spojuje statické kurzory, dlouhotrvající transakce.
  • Dotazy XML
  • Interní objekty vytvořené databázovým strojem SQL Server.
  • Obchody s verzemi
  • Více aktivních sad záznamů (MARS)

Více o TempDB si můžete přečíst v tomto článku.

SQL Server znovu vytvoří tuto databázi TempDB při restartu služby databázového stroje. Tento restart může být způsoben automatickým nebo ručním restartem služby SQL. Můžeme se dotazovat sys.databases pro zobrazení data vytvoření TempDB, což je také čas spuštění databázové služby:

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

Konfigurace databáze TempDB SQL Server a doporučené postupy

Někdy zaznamenáme neočekávaný nárůst databáze TempDB. Prvním krokem, jak se tomu vyhnout, je nakonfigurovat jej podle osvědčených postupů. V této části se podívejme na konfiguraci TempDB v různých verzích SQL Server.

Nakonfigurujte TempDB pro více souborů DATA s rovnoměrným růstem

Podle osvědčeného postupu bychom měli mít více datových souborů s rovnoměrným růstem všech souborů. Počet souborů závisí na logických procesorech.

Procesory

Počet datových souborů TempDB

Logické procesory menší nebo rovné osmi

Osm

Logické procesory větší než osm

Začněte s osmi datovými soubory.

Zvyšte datové soubory v násobcích čtyř a sledujte čítače výkonu pro spor TempDB.

Pro verze SQL Server před rokem 2016 nemáme během procesu instalace k dispozici konfiguraci.

Ve výchozím nastavení vytváří pouze jeden soubor dat a protokolu s následujícími konfiguracemi:

Primární soubor TempDB

Automaticky zvětšit datový soubor o deset procent (dokud není disk plný)

Soubor protokolu TempDB

Automaticky zvětšit datový soubor o deset procent (dokud se disk nezaplní nebo maximální velikost souboru protokolu nedosáhne 2 TB)

Konfigurace databáze SQL Server 2014 TempDB SQL Server

SQL Server 2016 poskytuje vylepšení konfigurace TempDB během procesu instalace podle osvědčeného postupu:

TempDB Primární a sekundární soubory

Automaticky narůst o 64 MB (do zaplnění disku)

Soubor protokolu TempDB

Automaticky narůst o 64 MB (do zaplnění disku nebo do maximální velikosti souboru protokolu 2 TB)

Konfigurace TempDB SQL Server 2016 a novější

Nerovnoměrný automatický růst databáze SQL Server TempDB

SQL Server používá metodu round-robin k vyplnění více datových souborů, pokud nemají stejnou velikost. Někdy vidíme, že jeden soubor se zvětší, ale ostatní soubory zůstanou minimální. V případě nestejnoměrných souborů používá SQL Server pro většinu dotazů větší soubor a bude dále růst:

  1. Použijte stejný automatický růst souborů TempDB (jak je uvedeno v předchozím bodě).
  2. Povolte příznak trasování 1117 pro sdružování všech datových souborů v databázi.

Druhý bod je opraven automaticky v SQL Server 2016 a novějších, ale měli byste jej povolit v dřívějších verzích. Tento příznak trasování nevyžadujeme v SQL Server 2016 a vyšších.

Scénáře růstu TempDB

V této části uvidíme několik scénářů růstu databáze SQL Server TempDB. V mé instanci SQL mám osm datových souborů s následující konfigurací:

Nyní proveďte následující dotaz, abyste vytvořili dočasnou tabulku a provedli vkládání dat. Umístěním dočasného úložiště tabulky je databáze TempDB. Tento dotaz používá operátor CROSS JOIN s více sloupci a dále třídí výsledky pomocí klauzule ORDER BY.

Poznámka: Nespouštějte tento dotaz v produkčním systému; Používám jej pouze pro účely demo.

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;

Tento dotaz bude trvat dlouho a může mít za následek vysoké využití procesoru i ve vašem systému. Zatímco je dotaz spuštěn, otevřete další okno dotazu a pomocí DMV sys.dm_db_task_space_usage získejte informace o alokace stránek a dealokace podle úkolu. Spojujeme toto DMV s dalšími DMV, abychom získali požadované informace pro SQL Server databázi 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;
Ve výstupu vidíme vnitřní počty stránek objektů a jejich velikosti (kbytes_used_internal) pro ID relace 55. Optimalizátor dotazů SQL Server provádějící tento dotaz v paralelním modelu; proto můžeme ve výstupu vidět více ID relace 71:

Můžete si také prohlédnout odhadovaný plán realizace a jak je uvedeno níže, máme dva nákladné operátory:

  • Paralelismus:47,3 %
  • Řazení:52,3 %

V operátoru řazení můžeme vidět vysoké odhadované náklady na operátora 138 576,5:

Následující dotaz používá DMV sys.dm_db_file_space_usage a připojí jej k sys.master_files, aby zkontroloval počet stránek s přidělenými a nepřidělenými oblastmi v databázi serveru SQL Server TempDB během provádění dotazu:

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

Můžeme sledovat provádění dotazu, jeho využití v databázi TempDB a v případě potřeby proces zabít, aby se místo okamžitě uvolnilo. Měli bychom také optimalizovat dotaz způsobující masivní růst TempDB.

Monitorujte využití databáze TempDB SQL Server pomocí rozšířených událostí

Rozšířené události jsou užitečné pro monitorování databáze TempDB. Pomocí dotazu můžeme přidat následující rozšířené události:

  • database_file_size_change
  • databases_log_file_used_size_changed

Vytvořit rozšířenou událost

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

Zahájit relaci rozšířené události

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

Nyní spusťte svou pracovní zátěž, abyste mohli používat databázi TempDB a rozšiřovat datové soubory. Rozšířené události zachycují růst datového souboru a dotaz, který tento nárůst způsobil.

Můžete buď zobrazit soubor relace rozšířené události v režimu GUI SSMS, nebo použít následující dotaz ke sledování růstu TempDB.

Sledování růstu 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;

Izolace snímku

Pro své dotazy můžete použít izolaci snímků. V tomto modelu izolace ukládá SQL Server aktualizované verze řádků každé transakce do TempDB. V případě velké nebo dlouhotrvající transakce můžete vidět obrovskou databázi TempDB.

Transakci můžete provést pomocí příkazu SET a specifikovat Snapshot isolation:

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

Můžete se také dotazovat na sys.databases systémový pohled pro kontrolu, zda má některá uživatelská databáze izolaci snímků.

Dotaz na povolení izolace snímků v databázi AdventureWorks

ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

Dotaz na kontrolu uživatelské databáze s izolací snímků

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

Na následujícím snímku obrazovky můžete vidět, že databáze AdventureWorks má izolaci snímků. Databáze TempDB má také izolaci snímků, ale v dotazu jsme vynechali database_id menší než 4:

K monitorování úložiště verzí v TempDB můžeme použít DMV sys.dm_db_file_space_usage:

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;

Zde vidíme, že velikost úložiště verzí je 67968 kB. U velké nebo dlouhotrvající transakce můžete vidět obrovskou velikost databáze TempDB serveru SQL Server kvůli tomuto úložiště verzí:

Dalším případem, který může způsobit velkou velikost úložiště verzí, je vždy sekundární replika pouze pro čtení. Pokud provedete jakýkoli dotaz na sekundární databázi, automaticky použije úroveň izolace snímku. Jak víte, úroveň izolace snímku zkopíruje verzi řádku v TempDB.

Měli byste sledovat následující čítače perfmon:

  • SQLServer:Transactions\Longest Transaction Running Time – Zachycuje nejrozšířenější aktivní transakci.
  • SQLServer:Transactions\Version Store Size (KB) – Zachycuje aktuální velikost všech úložišť verzí v TempDB.
  • SQLServer:Transactions\Version Cleanup rate (KB/s) ) – Toto počítadlo můžete použít k zobrazení rychlosti čištění verzí v TempDB
  • SQLServer:Transactions\Version Generation rate (KB/s) – Pomocí tohoto počítadla můžete zachytit rychlost zachycení úložiště verze.

Měli byste také sledovat růst TempDB pro verzování v Vždy na sekundární databázi. Zabijte dlouhotrvající relace, aby mohl vyčistit verzování a získat zpět místo v databázi TempDB.

Závěr

V tomto článku jsme se dozvěděli o osvědčených postupech databáze TempDB databáze SQL Server a různých metodách k detekci a zabránění neočekávanému růstu. TempDB byste měli pravidelně sledovat a konfigurovat různá upozornění, aby byla proaktivní.

  • Monitorování velikosti TempDB
  • Monitorování místa na disku
  • Dlouhotrvající transakce


  1. Nejbližší zápas, část 2

  2. Práce s JavaFX UI a JDBC aplikacemi

  3. Jak načíst názvy polí z dočasné tabulky (SQL Server 2008)

  4. Převést z data na epochu-Oracle