
Cleaning up TempDB
December 31, 2007In many significantly large production environments, the TempDB can regularly grow with little or no thought towards maintaining some control over the lifespan of tables. In most situations, TempDB is not used heavily enough to be a problem, but occasionally due to non-ideal code, many tables are created and left with no regular cleanup.
While I am a proponent of using Table Variables over Temp Tables, the fact remains that many developers, and a significant number of DBAs use Temp Tables, and it is left in the hands of the DBA to deal with any complications caused by this.
The most obvious flaw in using Temp Tables in a 24/7 Productions Environment, is that if your SQL Server box never reboots, your TempDB never gets cleaned out (unless it’s by the code that created the Temp Tables, and that never happens. To deal with this issue, I have created a SP that runs once an hour, deleting Temp Tables that are more than 12 hours old (unless they reside in a Table (TempTableToKeep) that I use to store the names of tables I want to keep, and the date/time to finally delete them.
The code:
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N’[dbo].[TempTableToKeep]‘) AND OBJECTPROPERTY(id, N’IsUserTable’) = 1)
DROP TABLE [dbo].[TempTableToKeep]
GO
CREATE TABLE [dbo].[TempTableToKeep] (
[TempTable] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[DateToDelete] [datetime] NOT NULL
) ON [PRIMARY]
GO
IF EXISTS (SELECT name FROM sysobjects WHERE name = N’sp_DropTempTables’ AND type = ‘P’)
DROP PROCEDURE sp_DropTempTables
GO
CREATE PROCEDURE sp_DropTempTables
AS
DECLARE @Cursor AS CURSOR
DECLARE @Name AS VARCHAR(100)
DECLARE @TableName AS SYSNAME
DECLARE @Owner AS VARCHAR(100)
DECLARE @SQL AS NVARCHAR(200)
SET @Cursor = CURSOR SCROLL FOR
SELECT tempdb.dbo.sysobjects.name, tempdb.dbo.sysobjects.*
FROM TempTableToKeep
RIGHT OUTER JOIN tempdb.dbo.sysobjects ON TempTableToKeep.TempTable = tempdb.dbo.sysobjects.name
WHERE ((tempdb.dbo.sysobjects.crdate < DATEADD(hh, -12, GETDATE())) AND (tempdb.dbo.sysobjects.type = ‘U’) AND (TempTableToKeep.DateToDelete < GETDATE())) OR
((tempdb.dbo.sysobjects.crdate < DATEADD(hh, -12, GETDATE())) AND (tempdb.dbo.sysobjects.type = ‘U’) AND (TempTableToKeep.DateToDelete IS NULL))
OPEN @Cursor
FETCH FIRST FROM @Cursor
INTO @Name, @Owner
WHILE (@@FETCH_STATUS = 0)
BEGIN
If (@@FETCH_STATUS = 0)
BEGIN
IF EXISTS(SELECT name FROM tempdb..sysobjects WHERE name = @Name AND type = ‘U’)
BEGIN
SET @SQL = ‘DROP TABLE tempdb..’ + @Name
–PRINT @SQL
EXECUTE sp_executesql @SQL
END
FETCH NEXT FROM @Cursor
INTO @Name
END
END
CLOSE @Cursor
DEALLOCATE @Cursor
GO


[...] The first article cover maintenance of the TempDB. [...]
THanks a lot… you are great!!!
Thanks for the comment. I hope this code helped you out.
At a past company, we had a ridiculous amount of code that created temporary tables and did not clean up after itself. This was my solution to keeping TempDB under control.
At my current position I’ve written most of the code myself, so TempDB is used much less frequently, and usually cleaned out when it is used, so it’s much less of an issue, but still a job that runs regularly, just to keep the server cleaned up.
I can’t get this to work? And I have some strange behavior on the tempdb.
I have been doing some testing and set to tempdb to start with 8MB and ‘By 10 percent, unrestricted growth’
I then create a temporary table and my tempdb (file) growth to aprox 1GB. If I then select shrink files in the task menu Currently allocated space is still 8MB and Available free spare is negative.
If I manually try to drop a the temporaty table I get this error: “Database name ‘tempdb’ ignored, referencing object in tempdb.
Msg 3701, Level 11, State 5, Line 1
Cannot drop the table ‘#temptabel2_________________________________________________________________________________________________________000000000008′, because it does not exist or you do not have permission.
”
How do I get permission to do this? So it will work?
If you don’t have rights to delete a table in tempDB manually this code won’t allow you to get around that. You’d need to make sure you have delete rights (DDLAdmin) in tempDB before testing this code.
Once you can delete a table manually, then try running this code, and make sure it deletes the older tables.
As it is designed, it deletes tables older than 12 hours, DATEADD(hh, -12, GETDATE()), which can be modified by changing the number of hours to something more appropriate for your organization. I’m make sure you don’t delete files under 30 minutes old, as they could still be in use by an application, but depending on your system, you may need to keep files older than that as well.
When I try to delete anything from the tempdb i get:
Msg 3701, Level 11, State 5, Line 1
Cannot drop the table ‘#IRD________________________________________________________________________________________________________________00000000132C’, because it does not exist or you do not have permission.
Jessie,
If you don’t have rights to delete a table in tempDB manually this code won’t allow you to get around that. You’d need to make sure you have delete rights (DDLAdmin) in tempDB before testing this code.
Once you can delete a table manually, then try running this code, and make sure it deletes the older tables.
I am logged onto the server via sql management studio as ’sa’. I am still not able to drop any of the temp tables (manually). Correction…I am able to drop the temp tables I created using the same query. I’m just not able to remove the temp tables left behind by other sp, etc… I suspect those tables may have been create using ’sa’. Would that matter?
Marty,
When you attempt to drop the tables, what message do you get? Do you not have perms, or is the table locked, or …?
One issue could be that the table is still being used, and thus locked, which is why the code above includes:
tempdb.dbo.sysobjects.crdate < DATEADD(hh, -12, GETDATE()
This ensures that only tables created at least 12 hours ago are deleted, as they are likely no longer in use (although you could raise or lower that time depending on your needs).
I get the same sort of message as Jessie did.
Cannot drop the table…Because it does not exist or you do not have permission.
I’m pretty sure these tables were created while I was developing a stored procedure. I had to reboot my PC for a non-related reason and forgot to drop the tables for these sessions. I would have thought just using an ’sa’ login would let me do this.
If you’ve got sysadmin rights are are still unable to drop the temp table (even manually using Management Studio) my guess would be that the table really does not exist;
To test this, do a SELECT on the temp table and see if it comes back with results
To fix this, either close Management Studio and see if it still shows up in TempDB after opening it back up; or restart the SQL Service on the server and then create a new temp table and try to delete that one
Another possibility is that the temp table is being locked by the SP or some other method, in which case you’d want to look at all your running processes, and see if any of them are holding a lock on that temp table.
Mdf file size in temp db is growing unto 25 GB.
Approximately 140 temporary are present which are not realized. Please give any suggestion except restarting the server.There is no opentransaction.
majeed,
There are no open processes, and yet you still can not delete the Temp Tables manually when logged in with SysAdmin rights?
If you can delete them manually you should also be able ot delete them using the code as described above in the main article.
Once the files are deleted, it’s a simple command to shrink the size of the database without having to restart the service.
[...] Posts Cleaning up TempDB (the fact that almost every month, this is my top read post makes me think that perhaps I need to [...]
[...] 13 random scientific questions I want answered Theory (Scientific vs layman’s definition) Cleaning up TempDB (the fact that almost every month, this is my top read post makes me think that perhaps I need to [...]