SELECT 错误 - 主文件组已满

pau*_*l23 5 etl sql-server-2008-r2

一个 SQL Server 2008 R2 数据库视图联合了几个事务表。几个月来查询一直很慢,开发团队正计划重新创建查询。我需要将结果 ETL 到一个平面文件中并从数据库中清除它们。当我尝试查询视图(500 万条记录)时,出现此错误:

消息 1105,级别 17,状态 2,第 1 行
无法为数据库“tempdb”中的对象“dbo.SORT 临时运行存储:140744470495232”分配空间,因为“PRIMARY”文件组已满。通过删除不需要的文件、删除文件组中的对象、向文件组添加其他文件或为文件组中的现有文件设置自动增长来创建磁盘空间。

我应该设置的推荐文件增长是多少,如何管理或解决此错误?提前致谢。

Mar*_*ian 5

最快的解决方法是重新启动 SQL Server,Tempdb 将使用默认大小和空文件重新创建。

但是,如果它是生产服务器,则无法在需要时真正重新启动它。真正的解决方法是在不同的驱动器上添加一个新文件并运行查询。

一个例子是(起始大小为 1 MB 的新文件,增加 100 MB,限制为 500 MB):

USE [master]
GO
ALTER DATABASE [tempdb] ADD FILE ( NAME = N'newtempfile', FILENAME = N'e:\newtempfile.ndf' , SIZE = 100MB, MAXSIZE = 500MB , FILEGROWTH = 100MB )
GO
Run Code Online (Sandbox Code Playgroud)

然后,当您有时间时,检查一下使用 Tempdb 的内容。但是可能您仍然需要 TempDB 的空间,因此您最好为此规划空间并为此数据库分配足够的空间,因为这对于健康的系统非常重要(您可以简单地将其视为 RAM 部分)。

PS1:检查您的选择语句中是否没有笛卡尔积,因为这个数字似乎有点高。

PS2:如果您在 TempDB 驱动器上有足够的可用空间,请检查文件是否未达到其限制并禁用自动增长。如果是,请启用自动增长(不是按百分比,而是按您觉得合适的特定大小)。

PS3:一个好的解决方案是将 ETL 过程分解为较小的事务。不要一次删除 1 Bil 记录,而是按 1000 次删除 .. 或使用批量大小,直到您对过程的长度和文件的大小感到安全为止。您可能会更快地获得结果,并且不会立即大幅增加空间。


小智 3

该错误很可能表明您的 tempdb 所在的硬盘驱动器已满。最简单的解决方案是插入一个新驱动器,并将临时数据库移到那里。

首先,通过在 tempdb 上下文中运行以下查询来找出组成 tempdb 的文件的名称:

EXEC sp_helpfile
GO
Run Code Online (Sandbox Code Playgroud)

使用上述脚本中的文件名更改以下脚本:

USE master
GO
ALTER DATABASE TempDB MODIFY FILE
  (NAME = tempdev, FILENAME = 'e\:<tempdb datafile>.mdf')
GO
ALTER DATABASE TempDB MODIFY FILE
  (NAME = templog, FILENAME = 'e:\<tempdb log>.ldf')
GO
Run Code Online (Sandbox Code Playgroud)

显然,替换E:\为新的驱动器号。

完成后,重新启动 SQL Server 以实际移动 tempdb,然后尝试查看是否解决了问题。