将数据库缩小到其初始大小以下


10

我有一个SQL Server 2005开发数据库,​​它是实时的30GB副本。我们删除了一些dev中不需要的数据,这使使用的数据文件空间减少到20GB。因此,我们约有33%的未使用。

我需要回收空间,这将允许我们在服务器上拥有第二个开发数据库(基于缩减版本);但是,我无法回收空间,我做了以下工作:

  • 文件的初始大小SMS2_Data为30GB。

    DBCC SHRINKFILE (N'SMS2_Data' , 0, TRUNCATEONLY)

    其次是

    DBCC SHRINKFILE (N'SMS2_Data' , 19500)

不开心 我尝试进行备份,创建一个初始大小较小的新数据库,然后还原,但由于初始大小被覆盖而感到不高兴。也尝试过:

ALTER DATABASE SMS2HazSub MODIFY FILE (NAME = 'SMS2_Data', SIZE = 20000) 

这是错误的,说:

修改文件失败。指定的大小小于当前大小。

我尝试了20800,然后一直提高到29000(29GB),但仍然不允许我更改它。

完成收缩后,将恢复模式从更改FULLSIMPLE,然后再次更改。不开心

我认为这与某些TEXT领域有关。我们整个系统中大约有6个。因此,作为测试,我将它们全部删除,然后缩小了文件,但仍然没有变化。

剩下的唯一选择是将数据重新导入到另一个数据库。这是不切实际的,因为必须在实时数据库上进行,因为这样做会带来很大的风险。我们半定期地获取实时数据库的副本并覆盖dev / test。我们有大约500张桌子。我想要一种不会将数据导出到新数据库的风险的方法。

我尝试将数据移动到另一个文件,它复制了除5%之外的所有数据。这就是导致我尝试删除所有文本列的原因。

服务器处于兼容模式90,但为SP2。我现在做了以下3次:重新索引所有表,备份数据库,收缩文件,收缩数据库。仍然没有喜悦。

EXECUTE sp_spaceused 返回:

database_name   database_size   unallocated space
SMS2Tests       31453.94 MB     13903.16 MB

reserved     data         index_size   unused
16545568 KB  10602264 KB  4254360 KB   1688944 KB

Answers:


3

正如某些人已经提到的那样,您可以创建新数据库并从旧数据库“复制”内容。这将是您的最佳选择。但是我注意到您想定期进行此操作。因此,最好的选择是Redgate Data CompareRedgate Compare。两者都是Redgate SqlToolbelt软件包的一部分。

那你干什么:

  1. 创建一个初始大小较小的空数据库。
  2. 使用Redgate Compare从旧数据库复制数据库结构,函数等
  3. 使用Redgate Data Compare将数据从旧数据库复制到新数据库
  4. 您在开发数据库上工作,然后随时可以进行数据比较并定期更新Dev DB,或者,如果对数据库进行了任何更改,则可以使用Redgate Compare部署这些更改,然后再进行Redgate Data Compare。

Data Compare的好处是,在一段时间后复制了30gb的数据(只能从某些表开始)之后,它只需要“比较”一些更改,而不是全部30gb的数据。这意味着与正常复制相比,它对两个数据库的影响要小得多。


2

这里有几种可能性。

首先,您使用的是SQL 2005 SP3还是更高版本?有些人报告了先前版本的SHRINKFILE问题(请参阅http://www.sqlservercentral.com/Forums/Topic981292-146-6.aspx#bm985164

其次,您可以验证数据库是否设置为模式90兼容性,而不是模式80吗?这显然是SQL 2000的问题,但是在SQL 2005中取消了限制。如果您的数据库仍设置为模式80兼容性,则可能仍然是问题。

第三,这可能是LOB数据(text,ntext,varchar(max))的问题。在这里查看Paul Randall的精彩文章

我假设您了解SHRINKing的真正作用,并且会对您的表现产生负面影响:

  • SHRINK的工作方式是将页面从文件末尾盲目移动到开头
  • 这样,它可能会可怕地使索引碎片化,从而可能导致严重的性能问题
  • 由于其数据密集型操作,因此收缩可能需要大量时间

我通常建议使用完全重新索引(将回收刚刚释放的一些空间)跟进收缩,但这听起来并不像您能够做到这一点。

如果您在活动监视器中查看收缩SPID,它似乎在做什么?(IO和CPU计数器更改)还是被阻止?我能想到的唯一的另一件事是数据库上是否还有其他活动阻止了收缩。确保当时没有其他活动的spid正在使用数据库。

在此过程中切换到简单恢复模式也是一个好主意,以防止日志增长过多。


1

如果您确实要这样做:

  • 设置为恢复模式为简单
  • 意识到: DBCC SHRINKDATABASE (MyDatabase, TRUNCATEONLY);

1

SHRINKDATABASE 只会(最多)将数据库缩小到其MinSize,这样对您无济于事。

当您尝试使用默认值通过SSMS UI收缩文件时,它使用'DBCC SHRINKFILE(N'MyDB',0,TRUNCATEONLY)'。该命令只会(最多)将文件缩小到最后分配的程度。

如果要将文件缩小到MinSize以下,只需将参数DBCC SHRINKFILE从0 更改为想要将文件缩小到MB的大小。如果可能的话,非零数字将指示SHRINKFILE将文件缩小到该大小。因此DBCC SHRINKFILE('MyDB', 300, TRUNCATEONLY),如果数据库有空间,则将文件缩小到300MB。

您可以通过运行以下命令查看MinSize:

DBCC TRACEON(3604)
go
DBCC PAGE('MyDB', 1, 0, 3) with tableresults
go

通过以下方式计算以MB为单位的MinSize:(MinSize * 8)/ 1024


0

如果数据库中的实际数据量为20003(mb),则“ SIZE = 20000”将太小。尝试使用21000或25000,看看是否可行。(请记住,1 GB = 1024 MB。)


0

尝试

DBCC SHRINKDATABASE (N'SMS2_Data' , 0)

我在这里有一个SQL 2005数据库上使用了此文件,为数据文件分配的空间从10.2 GB变为3 GB。

Fyi,这是一个漫长的过程,我的数据库花了19分钟多一点。


ps刚检查,我数据库的恢复模型设置为“简单”。

没什么区别,我很确定可以通过前端完成。

0

我假设您有一个逻辑名称为SMS2_Data的数据库文件。您在数据库中也有一个或多个事务日志文件。

您面临的挑战无法解决在数据库的当前副本上。您声明的重要信息是“数据库文件的原始大小为30 GB”。不幸的是,该文件不能缩小到小于其原始大小。

正如您已经体验到的那样,SHRINKDB和SHRINKFILE并未提供您想要的东西。这些命令遵循“不能缩小到小于原始大小”规则。因此,您只能将数据库缩小到原始大小且不能缩小。

数据库备份和还原到现有的较小数据库也不起作用。当您执行数据库还原时,数据库文件将还原为与备份期间相同的文件大小。并且,恢复模型(简单,完整等)与该问题无关。

而且,最后一个坏消息要点。您可能会考虑将其他较小的数据库文件添加到数据库中,将所有数据传输出30 GB文件,然后将其删除。不幸的是,这也不起作用,因为您无法从数据库中删除初始文件。

因此,最好的解决方案是将数据复制到另一个数据库。您在这里有一些选择,也许您已经意识到了。第一步是创建一个大小小于数据大小的新数据库。然后,您可以将数据库大小扩展到所需的大小。

您可以将SSIS视为一种将数据从一个数据库传输到另一个数据库的方法。您会发现一个复制数据库任务,可以帮助您。您可以使用以下步骤:

  1. 创建比源数据库小的数据库
  2. 使用传输数据库任务安装SSIS包。将任务设置为使用在线传输。
  3. 运行SSIS包。
  4. SSIS包可能会更改数据库大小以匹配源数据库大小。缩小此数据库,因为它的原始文件大小较小。

请参阅有关SSIS 传输数据库任务的其他信息。


0

数据库中一些未使用的空间是正常的。
如果您有很多大记录(例如,长字符串),则数据页中可能有很多未使用的空间(因为一条记录通常不会在页面之间分配)。
另一件事是填充因子-最初,聚簇索引不会100%完整创建,以避免在后续插入时进行页面拆分(昂贵的操作)。
如果从数据库中删除了很多数据,这些数据先前占用的空间将不会自动回收-它将分配给表。

尝试调用DBCC DBREINDEX (table_name, '', 100)数据库中的每个表-它会以100%的填充因子重建所有索引,因此数据将尽可能紧凑地放置。然后尝试再次缩小数据库。


0

我发现缩小SQL Server数据库可能很麻烦。感觉就像您必须做歌舞常规。

这是我通常经历的过程:

Backup Shrink数据库分别备份Backup Shrink日志和数据库文件。备份重复直到最后缩小为止。

为了使它最终起作用,我不得不执行此过程多达三遍。我们的数据库大小超过68 GB,其中有98%的未使用空间。经历了几次这种歌曲和舞蹈程序,但最终缩小到了1GB以下。


0

我本来尝试先将mdf文件的初始大小减小到29 000 MB,然后再减小到28,000,以检测到紧密匹配。

通过删除30%的数据来减少30%的数据库文件大小是不合理的。

您可以通过以下方式估算数据库中有多少未使用空间:

execute sp_spaceused

在数据库的上下文中(使用yourdatabaename;)
可以发布其执行结果吗?


更新:
我在上面发布了我的相关问题:


那不是很好。13903.16mb未分配空间。未使用的索引1688944 KB
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.