2

I am facing a serious issue in my production server where the temp DB grow exponantialy. Is there any way we can recover the tempDB space without restarting the SQL service?

Cheers Kannan.

ctrlShiftBryan
  • 27,092
  • 26
  • 73
  • 78
Kthevar
  • 1,547
  • 5
  • 14
  • 18

3 Answers3

5

I would ignore posts advising you to change the recovery model or limit the size of tempDB(!).

You need to track down the actual cause of the growth.

If you have the default trace turned on (it's on by default, out of the box), you can retrospectively find out what caused the growth by running this:

--check if default trace is enabled
if  exists (select 1 from sys.configurations where configuration_id = 1568)
BEGIN

declare @defaultTraceFilepath nvarchar(256)

--get the current trace rollover file
select @defaultTraceFilepath = CONVERT(varchar(256), value) from ::fn_trace_getinfo(0)
where property = 2

SELECT ntusername,loginname, objectname, e.category_id, textdata, starttime,spid,hostname, eventclass,databasename, e.name 
FROM ::fn_trace_gettable(@defaultTraceFilepath,0)
      inner join sys.trace_events e
            on eventclass = trace_event_id
       INNER JOIN sys.trace_categories AS cat
            ON e.category_id = cat.category_id
where 
      databasename = 'tempDB' and 
      cat.category_id = 2 and --database category
      e.trace_event_id in (92,93) --db file growth

END

Otherwise, you can start a SQL Profiler trace to capture these events. Turn on capturing of Auto Growth events, Sort Warnings and Join Warnings and look for cross joins, hash joins or missing join conditions.

SQL Server exposes a way to identify tempDB space allocations by currently executing queries, using DMVs:

-- This DMV query shows currently executing tasks and tempdb space usage
-- Once you have isolated the task(s) that are generating lots 
-- of internal object allocations, 
-- you can find out which TSQL statement and its query plan 
-- for detailed analysis
select top 10
  t1.session_id, 
  t1.request_id, 
  t1.task_alloc,
  t1.task_dealloc,  
  (SELECT SUBSTRING(text, t2.statement_start_offset/2 + 1,
          (CASE WHEN statement_end_offset = -1 
              THEN LEN(CONVERT(nvarchar(max),text)) * 2 
                   ELSE statement_end_offset 
              END - t2.statement_start_offset)/2)
     FROM sys.dm_exec_sql_text(sql_handle)) AS query_text,
 (SELECT query_plan from sys.dm_exec_query_plan(t2.plan_handle)) as query_plan
from      (Select session_id, request_id,
sum(internal_objects_alloc_page_count +   user_objects_alloc_page_count) as task_alloc,
sum (internal_objects_dealloc_page_count + user_objects_dealloc_page_count) as task_dealloc
       from sys.dm_db_task_space_usage 
       group by session_id, request_id) as t1, 
       sys.dm_exec_requests as t2
where t1.session_id = t2.session_id and 
(t1.request_id = t2.request_id) and 
      t1.session_id > 50
order by t1.task_alloc DESC

(Ref.)

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
  • Hey Mitch, Thanks for your valuable answer. Is there any way we can recover the DB sapce without restarting? – Kthevar Nov 19 '09 at 11:38
  • unless you fix the cause of the growth, there's little point as it will only grow again... – Mitch Wheat Nov 19 '09 at 13:55
  • in one of your comments to another answer, you mentioned a particular SP. Have you tracked down the cause of the growth? – Mitch Wheat Nov 19 '09 at 13:58
  • Are you using snapshot isolation ? – Mitch Wheat Nov 19 '09 at 14:44
  • You said **I would ignore posts advising you to change the recovery model or limit the size of tempDB(!)** But AFAIK, you can not change recovery model of TempDb. It is SIMPLE by default. – Zerotoinfinity May 26 '15 at 10:36
  • @Zerotoinfinity: Correct. The recovery model is simple. my statement that you quoted "I would ignore posts advising you to change the recovery model or limit the size of tempDB" is not inconsistent with that fact. – Mitch Wheat May 26 '15 at 10:39
  • @MitchWheat Oops ! Thanks... I am not a native English speaker and misunderstood your sentence. Sorry :) – Zerotoinfinity May 26 '15 at 10:42
2

You can use DBCC SHRINKFILE to shrink the tempdb files and recover some space.

DBCC SHRINKFILE ('tempdev', 1) DBCC SHRINKFILE ('templog', 1)

The filenames can be found in the sysfiles table.

You still need to discover the root cause, but this can give you some breathing room until you do. The amount of space you recover will depend on usage and other factors.

Also:

How to shrink the tempdb database in SQL Server

http://support.microsoft.com/kb/307487

Darryl Peterson
  • 2,250
  • 1
  • 16
  • 13
0

In SIMPLE mode, the tempdb database's log is constantly being truncated, and it can never be backed up. So check it is in Simple Mode

Tinku
  • 1,592
  • 1
  • 15
  • 27
  • Basically running the production server in single mode is bit risky. I cant recover all the backups. Is there any other way to recover the space in full recovery mode? – Kthevar Nov 19 '09 at 09:57
  • Can you let me know the tempdb log size? – Tinku Nov 19 '09 at 10:04
  • okay, just right click system database -> Tempdb -> properties ->Options -> Recovery Model . Is it Simple ? – Tinku Nov 19 '09 at 10:11
  • Man I dont want to change the recovery mode to single. I am currently using Fullr ecovery mode. – Kthevar Nov 19 '09 at 10:29
  • U need to change the recovery mode for tempdb Not of your db . I think it is not required to use full recovery mode for tempdb as it is not going to be backed up – Tinku Nov 19 '09 at 11:09
  • You can not change recovery mode of tempdb – Zerotoinfinity May 26 '15 at 10:46