Om temp DB-databasen för din SQL Server tar slut på utrymme kan det orsaka stora störningar i din produktionsmiljö och kan avbryta användarapplikationer från framgångsrik slutförande. Om du använder ett skript för att spåra temp DB-storlek, lägg till skriptet från den här artikeln för att identifiera grundorsaken till temp DB-fyllningen.
Tempdb full - ett vanligt scenario
Dåligt skrivna frågor kan skapa flera temporära objekt vilket resulterar i en växande tempdb-databas. Detta leder till diskutrymmesvarningar och kan orsaka serverproblem. SQL Server Databasadministratörer tycker att det är mycket svårt att krympa tempdb och väljer omedelbart att starta om servern. Om de har provat alla metoder för att krympa tempdb-databasen och den fortfarande inte krymper, är det sista alternativet att starta om SQL Service via konfigurationshanteraren. Då skulle dina diskutrymmesvarningar och även serverproblem upphöra. Det kan dock hända att omstart av tempdb inte är tillgänglig för dig om problemet har uppstått på en produktionsserver.
DBCC
I sådana fall finns det flera DBCC-kommandon som när du kör kan du krympa tempdb. Om du hade ställt in skript för att proaktivt övervaka tempdb-storleken kan du använda detta skript för att ta reda på fyllningar av tempdb. Från och med nu skulle detta skript köras på alla länkserver. Du kan styra det enkelt genom att sätta en var-klausul. Du kan låta skriptet köras endast när det finns ett problem med din tempdb. Tabellen @Tserver används för att lagra alla dina länkade servernamn. För en tempdb-databas, SQL-korruption skulle ändra status för databasen som SUSPECT och detta kommer att avbryta SQL Server tjänsten från början.
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
Författarintroduktion:
Neil Varley är en dataåterställningsexpert i DataNumen, Inc., som är världsledande inom teknik för återställning av data, inklusive återställa Outlook och Excel-programvara för återställningsprogramvara. För mer information besök www.datanumen.com