Pokud je dočasná databáze databáze vašeho SQL Server vyčerpá místo, může způsobit závažné narušení produkčního prostředí a může přerušit uživatelské aplikace od úspěšného dokončení. Pokud používáte skript ke sledování velikosti dočasné databáze, připojte skript z tohoto článku k identifikaci hlavní příčiny plnění dočasné databáze.
Tempdb full - běžný scénář
Špatně napsané dotazy mohou vytvořit několik dočasných objektů, což má za následek rostoucí databázi tempdb. To povede k upozorněním na nedostatek místa na disku a může způsobit problémy se serverem. SQL Server Správci databází shledávají, že zmenšení dočasné databáze je velmi obtížné, a proto se okamžitě rozhodnou pro restart serveru. Pokud jste vyzkoušeli všechny metody zmenšení dočasné databáze a stále se nezmenšuje, poslední možností je restartovat službu SQL Service prostřednictvím Správce konfigurace. Tím se zastaví upozornění na nedostatek místa na disku a problémy se serverem také. Restart dočasné databáze však nemusí být k dispozici, pokud k problému došlo na produkčním serveru.
DBCC
V takových případech existuje několik příkazů DBCC, které by při spuštění umožnily zmenšit tempdb. Pokud jste nastavili skripty pro proaktivní sledování velikosti databáze tempdb, můžete pomocí tohoto skriptu zjistit výplně databáze tempdb. Od této chvíle bude tento skript spuštěn na všech linkových serverech. Můžete to snadno ovládat vložením klauzule where. Skript můžete nastavit tak, aby byl spuštěn, pouze pokud je problém s vaší tempdb. Tabulka @Tserver se používá k ukládání všech vašich názvů propojených serverů. Pro databázi tempdb Poškození SQL by změnilo stav databáze jako PODEZŘENÍ a to by přerušilo SQL Server službu od spuštění.
DECLARE @Tserver TABLE
(
cserver VARCHAR(200)
)
INSERT INTO @Tserver
VALUES ('SERVERNAME')
DECLARE @LogTable TABLE
(
cservername VARCHAR(200),
cssionid SMALLINT,
callocmb BIGINT,
cdeallocmb BIGINT,
ctext VARCHAR(4000),
cstatement VARCHAR(4000)
)
DECLARE c1 CURSOR FOR
SELECT *
FROM @Tserver
DECLARE @cmd NVARCHAR(4000),
@server VARCHAR(200)
OPEN c1
FETCH next FROM c1 INTO @server
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = 'EXEC(''use tempdb Declare @Table1 table ( cdeallopages bigint, callopages bigint, cssionid smallint, creqstid int ) insert into @Table1 SELECT SUM(internal_objects_dealloc_page_count), SUM(internal_objects_alloc_page_count), session_id, request_id FROM sys.dm_db_task_space_usage WITH (NOLOCK) WHERE session_id <> @@SPID GROUP BY session_id, request_id declare @Table2 table ( cssionid smallint, callocmb bigint, cdeallocmb bigint, ctext varchar(4000), cstatement varchar(4000) ) insert into @Table2 SELECT TBL1.cssionid, TBL1.callopages * 1.0 / 128 , TBL1.cdeallopages * 1.0 / 128 , TBL3.text, ISNULL( NULLIF( SUBSTRING( TBL3.text, TBL2.statement_start_offset / 2, CASE WHEN TBL2.statement_end_offset < TBL2.statement_start_offset THEN 0 ELSE( TBL2.statement_end_offset - TBL2.statement_start_offset ) / 2 END ), '''''''' ), TBL3.text ) FROM @Table1 AS TBL1 INNER JOIN sys.dm_exec_requests TBL2 WITH (NOLOCK) ON TBL1.cssionid = TBL2.session_id AND TBL1.creqstid = TBL2.request_id OUTER APPLY sys.dm_exec_sql_text(TBL2.sql_handle) AS TBL3 OUTER APPLY sys.dm_exec_query_plan(TBL2.plan_handle) AS TBL4 WHERE TBL3.text IS NOT NULL OR TBL4.query_plan IS NOT NULL ORDER BY 3 DESC; Select * from @Table2'') at [' + @server + ']'
PRINT @cmd
INSERT INTO @LogTable
(cssionid,
callocmb,
cdeallocmb,
ctext,
cstatement)
EXEC(@cmd)
UPDATE @LogTable
SET cservername = @server
WHERE cservername IS NULL
FETCH next FROM c1 INTO @server
END
CLOSE c1
DEALLOCATE c1
SELECT *
FROM @LogTable
Úvod autora:
Neil Varley je odborníkem na obnovu dat DataNumen, Inc., která je světovým lídrem v oblasti technologií pro obnovu dat, včetně obnovit Outlook a excelové softwarové produkty pro obnovu. Pro více informací navštivte www.datanumen.com