如何找到您的 TempDB 已满的原因 SQL Server

立即分享:

如果您的临时 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

立即分享:

评论被关闭。