繁体   English   中英

如何缩小我的 SQL Server 数据库?

[英]How do I shrink my SQL Server Database?

我有一个大小接近 1.9Gb 的数据库,并且 MSDE2000 不允许超过 2.0Gb 的数据库

我需要缩小这个数据库(以及在不同客户端位置的许多其他数据库)。

我发现并删除了 1000 条被认为不需要的记录:这些记录占数据库中一些主要(最大)表的很大比例。 因此,假设现在应该可以检索很多空间是合理的。

所以现在我需要缩小数据库以解决丢失的记录。

  • 我执行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);

这是一个古老的问题,但我刚刚遇到它。

真正简短且正确的答案已经给出,并且拥有最多的选票。 那你是怎么收缩事务日志,这很可能是有机磷农药的问题。 并且当事务日志增长失控时,通常需要将其缩回,但应注意防止日志增长失控的未来情况。 dba.se上的这个问题解释了这一点。 基本上 - 首先不要让它通过适当的恢复模型、事务日志维护、事务管理等变得那么大。

但是在阅读这个关于缩小数据文件(甚至日志文件)的问题时,我脑海中更大的问题是为什么? 当你尝试时会发生什么不好的事情? 看起来好像完成了收缩操作。 现在在这种情况下,它在某种意义上是有意义的 - 因为 MSDE/Express 版本的上限为最大数据库大小。 但正确的答案可能是根据您的需要查看正确的版本。 如果您偶然发现了这个想要缩小生产数据库的问题,而这不是原因,那么您应该问问自己为什么? 题。

我不希望有人在网上搜索“如何缩小数据库”时遇到这个问题,并认为这是一件很酷或可以接受的事情。

收缩数据文件是一项特殊任务,应保留用于特殊场合。 考虑到当您收缩数据库时,您实际上是在分割索引。 考虑到当您收缩数据库时,您正在占用数据库可能有一天会重新增长的可用空间 - 有效地浪费了您的时间并招致收缩操作的性能损失,只是为了看到数据库再次增长。

我在几篇关于缩小数据库的博客文章中写过这个概念。 第一个想到的就是不要碰那个收缩按钮”。 我谈论这里概述的这些概念 - 以及“适当调整”数据库的概念。 最好确定您的数据库大小需要,计划未来增长并将其分配到该数量。 在 SQL Server 2005 及更高版本中为数据文件提供即时文件初始化,增长的成本较低 - 但我仍然更喜欢有一个适当的初始应用程序 - 并且我对数据库中的空白远不那么害怕一般不加思索地缩小。 :)

DBCC SHRINKDATABASE对我DBCC SHRINKDATABASE ,但这是它的完整语法:

DBCC SHRINKDATABASE ( database_name, [target_percent], [truncate] )

其中target_percent是数据库收缩后数据库文件中剩余可用空间的所需百分比。

truncate参数可以是:

NOTRUNCATE

使释放的文件空间保留在数据库文件中。 如果未指定,则释放的文件空间将释放给操作系统。

TRUNCATEONLY

将数据文件中任何未使用的空间释放给操作系统,并将文件缩小到最后分配的范围,在不移动任何数据的情况下减小文件大小。 不会尝试将行重定位到未分配的页面。 使用 TRUNCATEONLY 时会忽略 target_percent。

...是的 no_one 是对的,缩小数据库不是很好的做法,因为例如:

缩小数据文件是引入显着逻辑碎片的极好方法,因为它将页面从数据库文件分配范围的末尾移动到文件前面的某个位置...

收缩数据库会对数据库、服务器产生很大的影响......在你做之前想很多!

在网络上有很多关于它的博客和文章。

迟到的答案,但可能对其他人有用

如果 DBCC ShrinkDatabase/ShrinkFile 或 SSMS(任务/收缩/数据库)都无济于事,那么 Quest 和 ApexSQL 的工具可以完成工作,如果需要,甚至可以安排定期收缩。

前段时间我在免费试用中使用了后者来做到这一点,通过在本文末尾进行简短描述:

https://solutioncenter.apexsql.com/sql-server-database-shrink-how-and-when-to-schedule-and-perform-shrinking-of-database-files/

您需要做的就是安装 ApexSQL Backup,单击主功能区中的“收缩数据库”按钮,在弹出的窗口中选择数据库,然后单击“完成”。

你应该使用:

dbcc shrinkdatabase (MyDB)

它将缩小日志文件(保持 Windows 资源管理器打开并查看它发生的情况)。

您还需要缩小各个数据文件。

然而,缩小数据库并不是一个好主意。 例如见这里

“因此,假设现在应该可以收回很多空间是合理的。”

抱歉,如果我误解了这个问题,但您确定是数据库而不是日志文件占用了空间吗? 检查以查看数据库所在的恢复模型。它可能处于完整状态,这意味着日志文件永远不会被截断。 如果您不需要每个事务的完整记录,您应该能够更改为简单,这将截断日志。 您可以在此过程中缩小数据库。 假设一切顺利,过程如下:

  1. 备份数据库!
  2. 更改为简单恢复
  3. Shrink db(右键db,选择所有任务>收缩db->设置为10%可用空间)
  4. 验证空间是否已被回收,如果没有,您可能需要进行完整备份

如果这不起作用(或者当您尝试切换恢复模式时收到一条消息说“日志文件已满”),请尝试以下操作:

  1. 备份
  2. 杀死与数据库的所有连接
  3. 分离数据库(右键单击 > 分离或右键单击 > 所有任务 > 分离)
  4. 删除日志(ldf)文件
  5. 重新连接数据库
  6. 更改恢复模式

等等。

这是另一个解决方案:使用数据库发布向导将架构、安全性和数据导出到 sql 脚本。 然后,您可以使当前的数据库脱机并使用脚本重新创建它。

听起来有点愚蠢,但有几个优点。 首先,不会丢失数据。 您的原始数据库(只要您在删除数据库时不删除它!)是安全的,新数据库将大致尽可能小,并且您将拥有当前数据库的两个不同快照 - 一个准备就绪滚动,一个缩小 - 您可以选择备份。

尽管我需要在 MSSQL 2012 版本上使用 SHRINKFILE,但我还是看到了这篇文章,这自 2000 或 2005 版本以来就有点棘手了。 在阅读了与此问题相关的所有风险和问题后,我最终进行了测试。 长话短说,我得到的最好结果是使用MS SQL Server Management Studio

Right-Click the DB -> TASKS -> SHRINK -> FILES -> select the LOG file

删除数据,确保恢复模式简单,然后收缩(收缩数据库或收缩文件都有效)。 如果数据文件仍然太大,并且您使用堆来存储数据——也就是说,大表上没有聚集索引——那么您可能会遇到关于从堆中删除数据的问题: http : //support.microsoft.com /kb/913399

不确定这有多实用,取决于数据库的大小、表的数量和其他复杂性,但我:

  1. 对物理驱动器进行碎片整理
  2. 根据我的要求、空间、增长百分比等创建一个新数据库
  3. 使用简单的 ssms 任务将所有表从旧数据库导入到新数据库
  4. 为旧数据库上的所有表编写索引,然后在新数据库上重新创建索引。 根据需要扩展外键等。
  5. 根据需要重命名数据库,确认成功,删除旧的

您还必须修改数据和日志文件的最小大小。 DBCC SHRINKDATABASE会收缩里面的文件,你已经分配的数据。 要将文件缩小到小于其最小大小的大小,请使用 DBCC SHRINKFILE 并指定新大小。

我认为您可以通过从完全恢复到简单恢复的切换来删除所有日志。 右键单击您的数据库并选择Properties并选择Options并更改

  • Recovery modeSimple
  • Containment typeNone

从完整切换到简单

当您将恢复模式设置为简单(并启用自动收缩)时,SQL Server 仍有可能无法收缩日志。 它与日志中的检查点(或缺少检查点)有关。

所以第一次运行

DBCC CHECKDB

在你的数据库上。 之后,收缩操作应该像魅力一样工作。

通常我使用任务>收缩>文件菜单并选择带有重新组织页面选项的日志文件。

我最近做了这个。 我试图制作我的数据库的紧凑版本以在路上进行测试,但无论我删除了多少行,我都无法缩小它。 最终,在这个线程中的许多其他命令之后,我发现我的聚集索引在删除行后没有得到重建。 重建我的索引使我可以正确缩小。

DBCC SHRINKFILE(N'YourDatabaseName', 0);

DBCC SHRINKFILE(N'YourDatabaseName_log', 0);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM