我们的数据库目前为64 Gb,其中一个应用程序开始失败,并出现以下错误:
System.Data.SqlClient.SqlException
:无法在数据库'cnv.LoggedUnpreparedSpos'.'PK_LoggedUnpreparedSpos'
中为对象'travelgateway'
分配空间,因为'PRIMARY'
文件组已满。通过删除不需要的文件,删除文件组中的对象,向文件组添加其他文件或为文件组中的现有文件设置自动增长来创建磁盘空间。
我仔细检查了所有内容:允许单个文件组中的所有文件以合理的增量自动增长(数据文件为100 Mb,日志文件为10%),超过100 Gb的可用空间可用于数据库,tempdb
也设置为自动增长,驱动器上有足够的可用硬盘空间。
要解决问题,我将第二个文件添加到文件组,错误消失了。但我对这整个情况感到不安。
问题在哪里,伙计们?
答案 0 :(得分:26)
好的,搞定了。事实证明,数据库文件所在的NTFS卷严重碎片化。停止了SQL Server,对整个事情进行了碎片整理,从那以后一切都很好。
答案 1 :(得分:19)
安东,
作为最佳做法,不应在主文件组中创建用户对象。有带宽时,创建一个新文件组并移动用户对象并将系统对象保留为主要对象。
以下查询将帮助您识别每个文件中使用的空间以及行数最多的顶级表以及是否有任何堆。这是调查这个问题的一个很好的起点。
SELECT
ds.name as filegroupname
, df.name AS 'FileName'
, physical_name AS 'PhysicalName'
, size/128 AS 'TotalSizeinMB'
, size/128.0 - CAST(FILEPROPERTY(df.name, 'SpaceUsed') AS int)/128.0 AS 'AvailableSpaceInMB'
, CAST(FILEPROPERTY(df.name, 'SpaceUsed') AS int)/128.0 AS 'ActualSpaceUsedInMB'
, (CAST(FILEPROPERTY(df.name, 'SpaceUsed') AS int)/128.0)/(size/128)*100. as '%SpaceUsed'
FROM sys.database_files df LEFT OUTER JOIN sys.data_spaces ds
ON df.data_space_id = ds.data_space_id;
EXEC xp_fixeddrives
select t.name as TableName,
i.name as IndexName,
p.rows as Rows
from sys.filegroups fg (nolock) join sys.database_files df (nolock)
on fg.data_space_id = df.data_space_id join sys.indexes i (nolock)
on df.data_space_id = i.data_space_id join sys.tables t (nolock)
on i.object_id = t.object_id join sys.partitions p (nolock)
on t.object_id = p.object_id and i.index_id = p.index_id
where fg.name = 'PRIMARY' and t.type = 'U'
order by rows desc
select t.name as TableName,
i.name as IndexName,
p.rows as Rows
from sys.filegroups fg (nolock) join sys.database_files df (nolock)
on fg.data_space_id = df.data_space_id join sys.indexes i (nolock)
on df.data_space_id = i.data_space_id join sys.tables t (nolock)
on i.object_id = t.object_id join sys.partitions p (nolock)
on t.object_id = p.object_id and i.index_id = p.index_id
where fg.name = 'PRIMARY' and t.type = 'U' and i.index_id = 0
order by rows desc
答案 2 :(得分:18)
遇到同样的问题,最初碎片整理似乎有效。但这只是一段时间。结果是客户正在使用的服务器,运行Express version
并且许可限制大约为10gb
。
所以即使大小设置为"无限制",它也不是。
答案 3 :(得分:3)
我也遇到了同样的问题,初始dtabase大小设置为4Gb,自动增长由1Mb设置。数据库所在的虚拟加密TrueCrypt驱动器似乎有足够的空间。
我改变了一些(上述)事情:
DBCC SHRINKDATABASE('...')
一切都没有用(我可以插入更多的记录,但很快就遇到了同样的问题)。 Tobbi提到的页面文件让我尝试了更大的虚拟驱动器。 (即使我的驱动器不应该包含任何这样的系统文件,因为我在很多时候都没有安装它。)
当我这样做时,我遇到了一个TrueCrypt问题,如果我要存储大于4gb(as shown in this SuperUser question)的文件。
在最后两次之后我做得很好,我假设这最后一个做了伎俩。我认为TrueCrypt选择了一个 exfat </ em>文件系统(as described here),它将所有文件限制为4GB。 (所以我可能根本不需要放大驱动器,但我还是做了。)
这可能是一个非常罕见的边境案例,但也许对某人有帮助。
答案 4 :(得分:3)
做一件事, 转到数据库的属性 选择文件并增加数据库的初始大小 并将主文件组设置为自动增量。 重启sql server。
您可以像以前一样使用数据库。
答案 5 :(得分:2)
我发现这是因为:http://support.microsoft.com/kb/913399
SQL Server仅释放堆表使用的所有页面 满足下列条件:在此表上删除。一个 正在进行表级锁定。注意堆表是任何表 与聚簇索引无关。
如果未取消分配页面,则数据库中的其他对象不能 重用页面。
但是,在a中启用基于行版本控制的隔离级别时 SQL Server 2005数据库,即使一个页面也无法发布 正在举行表级锁定。
Microsoft的解决方案:http://support.microsoft.com/kb/913399
要解决此问题,请使用以下方法之一: 如果有行,请在DELETE语句中包含TABLOCK提示 未启用基于版本控制的隔离级别。例如,使用a 语句类似于以下内容:
从TableName WITH(TABLOCK)删除
注意表示表的名称。使用TRUNCATE TABLE语句是否要删除表中的所有记录。 例如,使用类似于以下内容的语句:
TRUNCATE TABLE TableName
在表的列上创建聚簇索引。更多 有关如何在表上创建聚簇索引的信息,请参阅 SQL中的“创建聚簇索引”主题
你会注意到链接的底部没有注意到它适用于SQL Server 2008,但我认为它确实
答案 6 :(得分:2)
我遇到了同样的问题。原因是虚拟内存文件“pagefile.sys”与我们的数据库(D:驱动器)的数据文件位于同一驱动器上。它的大小增加了一倍并且填满了磁盘,但是Windows并没有把它拿起来,也就是说,当我们实际上没有时,我们可以免费使用80 GB。
重新启动SQL服务器没有帮助,也许碎片整理会让操作系统有时间释放页面文件,但是我们只是重新启动了服务器,瞧,页面文件已经缩小,一切正常。
有趣的是,在我们调查的30分钟内,windows根本没有计算pagefile.sys的大小(80gb)。重新启动后窗口确实找到了页面文件并将其大小包含在总磁盘使用量中(现在为40gb - 仍然太大了)。
答案 7 :(得分:2)
请检查数据库的文件增长类型,如果限制使其不受限制
答案 8 :(得分:1)
以我的经验,当主文件(.mdf)没有空间来保存数据库的元数据时,会出现此消息。该文件包括系统表,它们仅将数据保存到其中。
在文件中留出一些空间,命令将再次起作用。 就这样,尽情享受
答案 9 :(得分:0)
我们的问题是硬盘驱动器的可用空间为零。