如果您的临时 DB 数据库 SQL Server 空间不足,它可能会导致您的生产环境发生重大中断,并且可能会中断用户应用程序的成功完成。 如果您使用脚本来跟踪临时数据库大小,请附加本文中的脚本以确定临时数据库填充的根本原因。
Tempdb full——常见场景
编写不佳的查询可能会创建多个临时对象,导致 tempdb 数据库不断增长。这最终会导致磁盘空间不足警报,并可能引发服务器问题。当许多查询语句无法正确执行时,就会造成严重后果。 SQL Server 数据库管理员发现缩小 tempdb 数据库非常困难,他们通常会选择重启服务器。如果尝试了所有缩小 tempdb 数据库的方法仍然无效,最后的选择是通过配置管理器重启 SQL Server 服务。这样,磁盘空间不足的警报就会停止,服务器问题也会得到解决。但是,如果问题发生在生产服务器上,重启 tempdb 可能就不可行了。
数据库管理中心
在这种情况下,有几个 DBCC 命令在运行时允许您收缩 tempdb。 如果您设置了脚本来主动监视 tempdb 大小,则可以使用此脚本找出 tempdb 的填充物。 截至目前,该脚本将在所有链接服务器上执行。 您可以通过放置一个 where 子句轻松控制它。 您可以使脚本仅在您的 tempdb 出现问题时执行。 @Tserver 表用于存储所有链接的服务器名称。 对于 tempdb 数据库, SQL损坏 会将数据库的状态更改为 SUSPECT,这将中断 SQL Server 从一开始提供服务。
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
作者简介:
Neil Varley 是一位数据恢复专家 DataNumen, Inc.,它是数据恢复技术领域的世界领先者,包括 恢复 Outlook 和 excel 恢复软件产品。 欲了解更多信息,请访问 datanumen.com