sql >> Database >  >> RDS >> Sqlserver

Hoe onverwachte groei van SQL Server-database TempDB te detecteren en te voorkomen?

Elke SQL Server-instantie bevat de systeem-SQL Server-database TempDB. Het is typerend voor alle databaseverbindingen en bijna elke query maakt gebruik van de TempDB-database. Het is als een hart voor de SQL Server-instantie. In de praktijk kunnen we niet zonder de TempDB-database.

Laten we een kort overzicht geven van de bewerkingen waarin SQL Server TempDB gebruikt.

  • Ordenen op en Groeperen op clausule
  • Index aanmaken en online index opnieuw opbouwen
  • De opslag van tijdelijke tabellen en tabelvariabelen bevindt zich in de TempDB-database.
  • Snapshot-isolatie en lees vastgelegde snapshot-isolatie
  • DBCC-opdrachten
  • Hash voegt zich bij statische cursors, langlopende transacties.
  • XML-query's
  • Interne objecten gemaakt door de SQL Server-database-engine.
  • Versiewinkels
  • Meerdere actieve recordsets (MARS)

U kunt meer lezen over TempDB in dit artikel.

SQL Server maakt deze TempDB-database opnieuw bij het opnieuw opstarten van de database-engine Service. Deze herstart kan het gevolg zijn van de automatische of handmatige herstart van SQL Service. We kunnen sys.databases opvragen voor het bekijken van de TempDB-creatiedatum die ook een opstarttijd is van de databaseservice:

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

TempDB SQL Server-databaseconfiguraties en best practices

Soms zien we onverwachte groei van de TempDB-database. De eerste stap om dit te voorkomen, is door het te configureren volgens de best practices. Laten we in deze sectie bekijken dat de TempDB-configuratie verschillende versies van SQL Server is.

Configureer TempDB voor meerdere DATA-bestanden met gelijkmatige groei

Volgens best practice zouden we meerdere gegevensbestanden moeten hebben met een gelijkmatige groei van alle bestanden. Het aantal bestanden hangt af van de logische processors.

Verwerkers

Aantal TempDB-gegevensbestanden

Logische processors kleiner dan of gelijk aan acht

Acht

Logische processors groter dan acht

Begin met acht gegevensbestanden.

Vergroot de gegevensbestanden in veelvouden van vier en controleer de prestatiemeteritems voor TempDB-conflicten.

Voor SQL Server-versies vóór 2016 hebben we geen configuratie beschikbaar tijdens het installatieproces.

Standaard maakt het slechts één gegevens- en logbestand met de volgende configuraties:

TempDB Primair bestand

Automatisch gegevensbestand met tien procent laten groeien (totdat de schijf vol is)

TempDB-logbestand

Gegevensbestand automatisch met tien procent laten groeien (totdat de schijf vol is of de maximale logbestandsgrootte 2 TB bereikt)

SQL Server 2014 TempDB SQL Server-databaseconfiguratie

SQL Server 2016 biedt verbeteringen voor TempDB-configuratie tijdens het installatieproces volgens de best practice:

TempDB Primaire en secundaire bestanden

Automatisch groeien met 64 MB (totdat de schijf vol is)

TempDB-logbestand

Automatisch groeien met 64 MB (totdat de schijf vol is of de maximale logbestandsgrootte 2 TB bereikt)

SQL Server 2016 en later TempDB-configuratie

Ongelijkmatige automatische groei SQL Server-database TempDB

SQL Server gebruikt een round-robin-methode om meerdere gegevensbestanden te vullen als ze niet dezelfde grootte hebben. Soms zien we dat het ene bestand enorm groeit, terwijl andere bestanden minimaal blijven groeien. In het geval van ongelijke bestanden, gebruikt SQL Server het grotere bestand voor de meeste zoekopdrachten, en het zou blijven groeien:

  1. Gebruik dezelfde automatische groei van TempDB-bestanden (zoals besproken in het vorige punt).
  2. Schakel traceervlag 1117 in om alle gegevensbestanden samen in een database te laten groeien.

Het tweede punt wordt automatisch opgelost in SQL Server 2016 en later, maar u moet het in eerdere versies inschakelen. We hebben deze traceringsvlag niet nodig in SQL Server 2016 en hoger.

TempDB-groeiscenario's

In deze sectie zullen we enkele scenario's zien voor de groei van de SQL Server-database TempDB. In mijn SQL-instantie heb ik acht gegevensbestanden met de volgende configuratie:

Voer nu de volgende query uit om een ​​tijdelijke tabel te maken en gegevens in te voegen. De tijdelijke tabelopslaglocatie is de TempDB-database. Deze query gebruikt een CROSS JOIN-operator met meerdere kolommen en sorteert de resultaten verder met behulp van de ORDER BY-component.

Opmerking: Voer deze query niet uit in het productiesysteem; Ik gebruik het alleen voor demo-doeleinden.

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;

Deze zoekopdracht zal lang duren en kan ook resulteren in een hoog CPU-gebruik in uw systeem. Terwijl de query wordt uitgevoerd, opent u een ander queryvenster en gebruikt u de DMV sys.dm_db_task_space_usage om informatie te krijgen over paginatoewijzing en deallocatie-activiteit per taak. We voegen deze DMV samen met andere DMV's om de vereiste informatie voor de SQL Server-database TempDB te krijgen:

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 de uitvoer zien we het aantal interne objectpagina's en hun grootte (kbytes_used_internal) voor de sessie-ID 55. SQL Server-queryoptimalisatieprogramma voert deze query uit in een parallel model; daarom kunnen we meerdere sessie-ID 71 in de uitvoer zien:

U kunt ook het geschatte uitvoeringsplan bekijken, en zoals hieronder wordt weergegeven, krijgen we twee dure operators:

  • Parallelisme:47,3%
  • Sorteren:52,3%

In de sorteeroperator zien we hoge geschatte operatorkosten 138.576.5:

De volgende query gebruikt DMV sys.dm_db_file_space_usage en voegt het samen met sys.master_files om de toegewezen en niet-toegewezen paginatellingen in de SQL Server-database TempDB te controleren terwijl de query wordt uitgevoerd:

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

We kunnen de uitvoering van de query, het gebruik ervan in de TempDB-database volgen en indien nodig het proces beëindigen om de ruimte onmiddellijk vrij te maken. We moeten ook de zoekopdracht optimaliseren die een enorme TempDB-groei veroorzaakt.

Bewaak het TempDB-gebruik van de SQL Server-database met behulp van uitgebreide gebeurtenissen

Uitgebreide gebeurtenissen zijn handig voor het bewaken van de TempDB-database. We kunnen de volgende uitgebreide gebeurtenissen toevoegen met behulp van de query:

  • database_file_size_change
  • databases_log_file_used_size_changed

Maak uitgebreid evenement

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

Start uitgebreide evenementsessie

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

Voer nu uw werklast uit om de TempDB-database te gebruiken en de gegevensbestanden te laten groeien. De uitgebreide gebeurtenissen registreren de groei van gegevensbestanden en de zoekopdracht die deze groei heeft veroorzaakt.

U kunt het uitgebreide gebeurtenissessiebestand in de SSMS GUI-modus bekijken of de volgende query gebruiken om de TempDB-groei te volgen.

Bewaak TempDB-groei

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;

Isolatie momentopname

U kunt snapshot-isolatie gebruiken voor uw query's. In dit isolatiemodel slaat SQL Server de bijgewerkte rijversies van elke transactie op in de TempDB. In het geval van een grote of langlopende transactie, kunt u een enorme TempDB-database zien.

U kunt de transactie uitvoeren met het SET-commando en Snapshot-isolatie specificeren:

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

U kunt ook sys.databases . opvragen systeemweergave om te controleren of een gebruikersdatabase snapshot-isolatie heeft.

Query om snapshot-isolatie in de AdventureWorks-database in te schakelen

ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

Query om gebruikersdatabase te controleren met snapshot-isolatie

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

In de volgende schermafbeelding kunt u zien dat de AdventureWorks-database snapshot-isolatie heeft. TempDB-database heeft ook snapshot-isolatie, maar in de query hebben we database_id minder dan 4 overgeslagen:

We kunnen DMV sys.dm_db_file_space_usage gebruiken om de versieopslag in de TempDB te controleren:

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 kunnen we zien dat de grootte van de versiewinkel 67968 KB is. Voor een grote of langlopende transactie kunt u een enorme SQL Server-database TempDB-grootte zien vanwege deze versieopslag:

Een ander geval dat een enorme omvang van het versiearchief kan veroorzaken, is altijd op alleen-lezen secundaire replica. Als u een query uitvoert op de secundaire database, wordt automatisch het momentopname-isolatieniveau gebruikt. Zoals u weet, kopieert het snapshot-isolatieniveau de rijversie in de TempDB.

U dient de volgende prestatietellers in de gaten te houden:

  • SQLServer:Transactions\Longest Transaction Running Time – Het legt de meest uitgebreide actieve transactie vast.
  • SQLServer:Transactions\Version Store Size (KB) – Het legt de huidige grootte vast van alle versie-archieven in TempDB.
  • SQLServer:Transactions\Version Cleanup rate (KB/s ) – U kunt deze teller gebruiken om de snelheid van het opschonen van versies in TempDB weer te geven
  • SQLServer:Transactions\Version Generation rate (KB/s) - U kunt de opnamesnelheid van de versie opslaan met behulp van deze teller.

U moet ook de TempDB-groei controleren voor het versiebeheer in Always op de secundaire database. Stop de langlopende sessies zodat het versiebeheer kan worden vrijgemaakt en ruimte kan worden vrijgemaakt in de TempDB-database.

Conclusie

In dit artikel hebben we geleerd over de best practice van de SQL Server-database TempDB-database en verschillende methoden om onverwachte groei te detecteren en te voorkomen. U moet TempDB regelmatig controleren en verschillende waarschuwingen configureren om proactief te zijn.

  • Bewaking van TempDB-grootte
  • Bewaking van schijfruimte
  • Langlopende transacties


  1. Een Oracle-database migreren van AWS EC2 naar AWS RDS, deel 4

  2. Installeren en werken met MySQL 5 op Windows 7

  3. Sql-bestand in Windows importeren naar postgresql

  4. Hoe kan ik een FULL OUTER JOIN doen in MySQL?