如何缩小我的SQL Server数据库?
我有一个大小为1.9Gb数据库的数据库,MSDE2000不允许超过2.0Gb的数据库
我需要缩小这个数据库(和许多这样的客户端位置)。
我发现并删除了1000多个被认为不需要的logging中的100多个logging:这些logging在数据库中的一些主要(最大)表中占很大比例。 因此,假设现在可以检索的空间是合理的。
所以现在我需要缩小数据库来弥补缺失的logging。
- 我执行
DBCC ShrinkDatabase('MyDB')
……没有效果。 - 我已经尝试了MSSMS提供的各种缩小设施….仍然没有效果。
- 我已经备份了数据库,并恢复它…仍然没有效果。
还有1.9Gb
为什么?
无论我最终发现什么程序都需要在客户端机器上重放,并且只能访问OSQL或类似的东西。
ALTER DATABASE MyDatabase SET RECOVERY SIMPLE GO DBCC SHRINKFILE (MyDatabase_Log, 5) GO ALTER DATABASE MyDatabase SET RECOVERY FULL GO
这可能看起来很奇怪,但它对我很有帮助,而且我写了一个C#程序来自动执行此操作。
步骤1:截断事务日志(仅备份事务日志,打开选项以删除不活动的事务)
第2步:运行数据库收缩,将所有页面移动到文件的开头
步骤3:再次截断事务日志,如步骤2添加日志条目
第4步:再次运行数据库收缩。
我使用SQL DMO库的精简代码如下所示:
SQLDatabase.TransactionLog.Truncate(); SQLDatabase.Shrink(5, SQLDMO.SQLDMO_SHRINK_TYPE.SQLDMOShrink_NoTruncate); SQLDatabase.TransactionLog.Truncate(); SQLDatabase.Shrink(5, SQLDMO.SQLDMO_SHRINK_TYPE.SQLDMOShrink_Default);
这是一个古老的问题,但我刚刚发生。
已经给出了真正简短而正确的答案,得票最多。 这就是如何缩小事务日志,这可能是OP的问题。 而当事务日志失控时,往往需要缩短,但应注意防止未来的日志失控。 这个关于dba.se的问题解释说。 基本上 – 不要让它通过适当的恢复模式,交易日志维护,交易pipe理等,得到这么大的。
但是在阅读这个关于收缩数据文件(甚至是日志文件)的问题时,我脑海中的更大的问题是为什么呢? 当你尝试什么坏事发生? 看起来收缩操作已经完成了。 现在在这种情况下,从某种意义上讲是有道理的 – 因为MSDE / Express版本的最大数据块大小是封闭的。 但是正确的答案可能是根据您的需求来查看正确的版本。 如果你偶然发现这个问题,希望缩小你的生产数据库,这不是原因,你应该问自己为什么? 题。
我不希望有人在网上search“如何缩小数据库”,并认为这是一个很酷或可以接受的事情。
收缩数据文件是一个特殊的任务,应该为特殊场合保留。 考虑当你缩小数据库时,你正在有效地分割你的索引。 考虑一下,当你缩小数据库时,数据库可能会有一天的增长空间被浪费掉,浪费你的时间,导致收缩操作的性能下降,只能看到数据库再次增长。
我在几篇关于收缩数据库的博客文章中写了这个概念。 这个名为“ 不要碰那个缩水button ”首先想到。 我讨论这里概述的这些概念,而且还谈到数据库的“正确大小”的概念。 决定你的数据库规模需要多less,计划未来的增长并将其分配到这个数量是好得多的。 随着即时文件初始化在SQL Server 2005及更高版本的数据文件中可用,增长的成本更低 – 但我仍然喜欢有一个正确的初始应用程序 – 我对数据库中的空白恐惧less于我的总的来说,一开始就没有想过收缩。 🙂
您还需要缩小个别数据文件。
然而缩小数据库不是一个好主意。 例如在这里看到
你应该使用:
dbcc shrinkdatabase (MyDB)
它会缩小日志文件(保持一个Windows资源pipe理器打开,看到它发生)。
DBCC SHRINKDATABASE
适用于我,但这是它的完整语法:
DBCC SHRINKDATABASE ( database_name, [target_percent], [truncate] )
其中target_percent
是数据库收缩后数据库文件中剩余可用空间的所需百分比。
truncate
参数可以是:
NOTRUNCATE
导致释放的文件空间保留在数据库文件中。 如果未指定,释放的文件空间将释放到操作系统。
TRUNCATEONLY
导致数据文件中任何未使用的空间释放到操作系统,并将文件缩小到最后分配的范围,减less文件大小而不移动任何数据。 没有尝试将行重定位到未分配的页面。 当使用TRUNCATEONLY时,target_percent被忽略。
…是的no_one是正确的,缩小datbase是不是很好的做法,因为例如:
数据文件的缩小是引入重要的逻辑碎片的极好的方法,因为它将页面从数据库文件的分配范围的末端移动到文件的前面。
收缩数据库可以在数据库,服务器上有很多的后果….在做这件事之前想想很多!
在网上有很多关于它的博客和文章。
迟到的答案,但可能对别人有用
如果DBCC ShrinkDatabase / ShrinkFile或SSMS(Tasks / Shrink / Database)都不起作用,那么Quest和ApexSQL中的工具可以完成工作,甚至可以安排在需要时定期收缩。
我已经在免费试用中使用了后者,前段时间通过在本文末尾简短地描述了这一点:
您只需安装ApexSQL Backup,单击主function区中的“收缩数据库”button,在popup的窗口中select数据库,然后单击“完成”。
这是另一个解决scheme:使用数据库发布向导将您的模式,安全性和数据导出到SQL脚本。 然后,您可以将当前的数据库脱机,并使用脚本重新创build它。
听起来很愚蠢,但有一些好处。 首先,不会丢失数据。 你的原始数据库(只要你在删除数据库时不删除你的数据库)是安全的,新的数据库将尽可能小,你将有两个不同的当前数据库快照 – 一个滚动,缩小 – 你可以select备份。
“因此,假设现在应该可以回收大量的空间是合理的。”
道歉,如果我误解了这个问题,但你确定它是数据库,而不是日志文件正在使用的空间? 检查数据库所在的恢复模式。有可能是Full,这意味着日志文件不会被截断。 如果您不需要每个事务的完整logging,则应该能够更改为简单,这将截断日志。 你可以在这个过程中收缩数据库。 假设事情正确,过程如下所示:
- 备份数据库!
- 更改为简单恢复
- 收缩数据库(右键单击数据库,select所有任务>收缩数据库 – >设置为10%的可用空间)
- validation空间是否已被回收,如果没有,则可能需要执行完整备份
如果这不起作用(或者当您尝试切换恢复模式时收到“日志文件已满”的消息),请尝试以下操作:
- 备用
- 杀死所有连接到数据库
- 分离数据库(右键单击>分离或右键单击>所有任务>分离)
- 删除日志(ldf)文件
- 重新连接数据库
- 更改恢复模式
等等
我遇到这个post,即使我需要SHRINKFILE在MSSQL 2012版本这是2000年或2005年版本有点棘手。 在阅读了与这个问题有关的所有风险和问题之后,我结束了testing。 长话短说,我得到的最好结果是使用MS SQL Server Management Studio 。
Right-Click the DB -> TASKS -> SHRINK -> FILES -> select the LOG file
您还必须修改数据和日志文件的最小大小。 DBCC SHRINKDATABASE将缩小已经分配的文件内的数据。 要将文件缩小到小于最小大小的大小,请使用DBCC SHRINKFILE并指定新的大小。
删除数据,确保恢复模型是简单的,然后减less(收缩数据库或收缩文件工程)。 如果数据文件仍然太大,并且您使用堆来存储数据 – 即在大型表上没有聚集索引 – 那么您可能会遇到有关从堆中删除数据的问题: http : //support.microsoft.com / KB / 913399
我最近做了这个。 我试图做一个紧凑版本的数据库在路上进行testing,但是我无法让它缩小,不pipe我删除了多less行。 最后,在这个线程中的许多其他命令之后,我发现删除行之后,我的聚簇索引没有得到重build。 重build我的索引,使我可以适当缩小。
不知道这将是多么实际,并根据数据库的大小,表的数量和其他复杂性,但我:
- 碎片整理物理驱动器
- 根据我的要求,空间,百分比增长等创build一个新的数据库
- 使用简单的ssms任务将旧数据库中的所有表导入新数据库
- 编写旧数据库上所有表的索引,然后在新数据库上重新创build索引。 根据需要扩展外键等
- 根据需要重命名数据库,确认成功,删除旧的