Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come rilevare e prevenire la crescita imprevista del database di SQL Server TempDB

Ogni istanza di SQL Server contiene il database di SQL Server di sistema denominato TempDB. È tipico per tutte le connessioni al database e quasi tutte le query utilizzano il database TempDB. È come un cuore per l'istanza di SQL Server. In pratica, non possiamo lavorare senza il database TempDB.

Facciamo un breve riepilogo delle operazioni in cui SQL Server utilizza TempDB.

  • Ordina per e raggruppa per clausola
  • Creazione dell'indice e ricostruzione dell'indice online
  • L'archiviazione di tabelle tempo e variabili di tabella è nel database TempDB.
  • Isolamento snapshot e lettura dell'isolamento snapshot commit
  • Comandi DBCC
  • L'hash si unisce a cursori statici, transazioni di lunga durata.
  • Query XML
  • Oggetti interni creati dal motore di database di SQL Server.
  • Versione negozi
  • Set di record attivi multipli (MARS)

Puoi leggere di più su TempDB in questo articolo.

SQL Server ricrea questo database TempDB al riavvio del servizio del motore di database. Questo riavvio può essere dovuto al riavvio automatico o manuale del servizio SQL. Possiamo interrogare sys.databases per visualizzare la data di creazione di TempDB che è anche un'ora di avvio del servizio di database:

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

Configurazioni del database di TempDB SQL Server e best practice

A volte, notiamo una crescita inaspettata del database TempDB. Il primo passo per evitarlo è configurarlo secondo le migliori pratiche. In questa sezione, vediamo la configurazione di TempDB in diverse versioni di SQL Server.

Configura TempDB per più file DATI con una crescita uniforme

Secondo la migliore pratica, dovremmo avere più file di dati con una crescita uniforme di tutti i file. Il numero di file dipende dai processori logici.

Processori

Numero di file di dati TempDB

Processori logici inferiori o uguali a otto

Otto

Processori logici maggiori di otto

Inizia con otto file di dati.

Aumenta i file di dati in multipli di quattro e monitora i contatori delle prestazioni per la contesa di TempDB.

Per le versioni di SQL Server precedenti al 2016, non è disponibile la configurazione durante il processo di installazione.

Per impostazione predefinita, crea un solo file di dati e log con le seguenti configurazioni:

File principale TempDB

Aumenta automaticamente il file di dati del dieci percento (fino a quando il disco non è pieno)

File di registro TempDB

Aumento automatico del file di dati del dieci percento (fino a quando il disco non è pieno o la dimensione massima del file di registro raggiunge i 2 TB)

Configurazione del database di SQL ServerSQL Server 2014 TempDB

SQL Server 2016 offre miglioramenti per la configurazione di TempDB durante il processo di installazione secondo la procedura consigliata:

TempDB File primari e secondari

Aumenta automaticamente di 64 MB (fino a quando il disco non è pieno)

File di registro TempDB

Aumento automatico di 64 MB (fino a quando il disco non è pieno o la dimensione massima del file di registro raggiunge i 2 TB)

Configurazione di SQL Server 2016 in poi TempDB

TempDB database SQL Server con crescita non uniforme

SQL Server utilizza un metodo round robin per riempire più file di dati se non hanno le stesse dimensioni. A volte, vediamo che un file diventa enorme, ma altri file rimangono una crescita minima. In caso di file irregolari, SQL Server utilizza il file più grande per la maggior parte delle query e continuerà a crescere:

  1. Utilizza la stessa crescita automatica dei file TempDB (come discusso nel punto precedente).
  2. Abilita il flag di traccia 1117 per far crescere tutti i file di dati insieme in un database.

Il secondo punto viene corretto automaticamente in SQL Server 2016 in poi, tuttavia dovresti abilitarlo nelle versioni precedenti. Non è necessario questo flag di traccia in SQL Server 2016 e versioni successive.

Scenari di crescita di TempDB

In questa sezione, vedremo alcuni scenari per la crescita di TempDB del database di SQL Server. Nella mia istanza SQL, ho otto file di dati con la seguente configurazione:

Ora, esegui la seguente query per creare una tabella temporanea ed eseguire l'inserimento dei dati. Il percorso di archiviazione della tabella temporanea è il database TempDB. Questa query utilizza un operatore CROSS JOIN con più colonne e ordina ulteriormente i risultati utilizzando la clausola ORDER BY.

Nota: Non eseguire questa query nel sistema di produzione; Lo sto usando solo a scopo dimostrativo.

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;

Questa query richiederà molto tempo e potrebbe comportare un utilizzo elevato della CPU anche nel sistema. Mentre la query è in esecuzione, apri un'altra finestra della query e utilizza il DMV sys.dm_db_task_space_usage per ottenere informazioni su allocazione di pagine e attività di deallocazione da parte dell'attività. Ci uniamo a questo DMV con altri DMV per ottenere le informazioni richieste per il database TempDB di SQL Server:

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;
Nell'output, vengono visualizzati i conteggi delle pagine degli oggetti interni e le relative dimensioni (kbytes_used_internal) per l'ID sessione 55. Query Optimizer di SQL Server esegue questa query in un modello parallelo; pertanto, possiamo vedere più sessioni ID 71 nell'output:

Puoi anche visualizzare il piano di esecuzione stimato e, come mostrato di seguito, otteniamo due operatori costosi:

  • Parallelismo:47,3%
  • Ordinamento:52,3%

Nell'operatore di ordinamento, possiamo vedere un costo dell'operatore stimato elevato 138.576,5:

La query seguente utilizza DMV sys.dm_db_file_space_usage e si unisce a sys.master_files per controllare i conteggi delle pagine dell'estensione allocata e non allocata nel database di SQL Server TempDB mentre la query è in esecuzione:

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

Possiamo monitorare l'esecuzione della query, il suo utilizzo nel database TempDB e, se necessario, interrompere il processo per liberare immediatamente lo spazio. Dovremmo anche ottimizzare la query che causa una crescita massiccia di TempDB.

Monitoraggio dell'utilizzo del database TempDB del database SQL Server utilizzando eventi estesi

Gli eventi estesi sono utili per il monitoraggio del database TempDB. Possiamo aggiungere i seguenti eventi estesi usando la query:

  • database_file_size_change
  • databases_log_file_used_size_changed

Crea evento esteso

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

Inizia la sessione estesa dell'evento

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

Ora, esegui il tuo carico di lavoro per utilizzare il database TempDB e far crescere i file di dati. Gli eventi estesi acquisiscono la crescita del file di dati e la query che ha causato questa crescita.

È possibile visualizzare il file della sessione di eventi estesi in modalità GUI di SSMS o utilizzare la query seguente per monitorare la crescita di TempDB.

Monitoraggio della crescita di 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;

Isolamento snapshot

Potresti utilizzare l'isolamento dello snapshot per le tue query. In questo modello di isolamento, SQL Server archivia le versioni di riga aggiornate di ogni transazione nel TempDB. In caso di una transazione di grandi dimensioni o di lunga durata, puoi vedere un enorme database TempDB.

Puoi eseguire la transazione con il comando SET e specificare l'isolamento dello snapshot:

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

Puoi anche interrogare sys.databases vista di sistema per verificare se qualsiasi database utente ha l'isolamento dello snapshot.

Query per abilitare l'isolamento degli snapshot nel database AdventureWorks

ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

Query per controllare il database degli utenti con l'isolamento degli snapshot

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

Nella schermata seguente puoi vedere che il database AdventureWorks ha l'isolamento dello snapshot. Il database TempDB ha anche l'isolamento dello snapshot, ma nella query abbiamo saltato database_id meno di 4:

Possiamo usare DMV sys.dm_db_file_space_usage per monitorare l'archivio delle versioni nel 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;

Qui, possiamo vedere che la dimensione dell'archivio della versione è 67968 KB. Per una transazione di grandi dimensioni o di lunga durata, è possibile visualizzare un'enorme dimensione TempDB del database di SQL Server a causa di questo archivio versioni:

Un altro caso che potrebbe causare una dimensione enorme dell'archivio versioni è la replica secondaria di sola lettura sempre attiva. Se si esegue una query sul database secondario, viene utilizzato automaticamente il livello di isolamento dello snapshot. Come sai, il livello di isolamento dello snapshot copia la versione della riga nel TempDB.

Dovresti monitorare i seguenti contatori di prestazioni:

  • SQLServer:Transazioni\Tempo di esecuzione della transazione più lungo – Cattura la transazione attiva più estesa.
  • SQLServer:Transazioni\Dimensioni archivio versione (KB) – Acquisisce la dimensione corrente di tutti gli archivi di versione in TempDB.
  • SQLServer:Transazioni\Tasso di pulizia della versione (KB/s ) – È possibile utilizzare questo contatore per mostrare il tasso di pulizia della versione in TempDB
  • SQLServer:Transazioni\Tasso di generazione versione (KB/s) – Puoi acquisire la velocità di acquisizione dell'archivio versioni utilizzando questo contatore.

È necessario monitorare la crescita di TempDB anche per il controllo delle versioni in Sempre nel database secondario. Termina le sessioni di lunga durata in modo che possa cancellare il controllo delle versioni e recuperare spazio nel database TempDB.

Conclusione

In questo articolo, abbiamo appreso la procedura consigliata per il database TempDB del database SQL Server e diversi metodi per rilevare e prevenire una crescita imprevista. Dovresti monitorare regolarmente TempDB e configurare diversi avvisi per essere proattivi.

  • Monitoraggio delle dimensioni di TempDB
  • Monitoraggio dello spazio di guida
  • Transazioni di lunga durata