如何从SQL Server 2008中删除.ldf文件?

45

如果我停止SQL服务器,然后删除数据库的.LDF文件(事务日志文件),会发生什么?数据库会被标记为可疑状态还是SQL服务器会自动创建一个新的?SQL Server 2008 R2

我的.LDF文件太大了,该如何管理呢?可以收缩它或删除它吗?请在查询表单中提供建议。


11
不要那样做!你将会失去整个事务日志。为什么你想要删除事务日志?它是你数据库的一个重要组成部分!不要在SQL Server背后随意删除文件 - 永远不要这样做! - marc_s
2
阅读此链接:https://dev59.com/xnRB5IYBdhLWcg3w4bAo - Alex K.
6个回答

55

不要删除任何数据库文件,因为这可能会严重损坏您的数据库!

如果磁盘空间不足,您可以将数据库分成多个部分。这可以在数据库的属性中完成。因此,您可以将数据库的每个部分放入不同的存储卷中。

如果您将恢复模式从完整模式更改为简单模式,则还可以收缩事务日志文件,使用以下命令:

ALTER DATABASE myDatabase SET RECOVERY SIMPLE
DBCC SHRINKDATABASE (myDatabase , 5)

切换回完整恢复模式也是可能的:

ALTER DATABASE myDatabase SET RECOVERY FULL

关于 SHRINKDATABASE 的更新 - 或者是我回答这个问题时不知道的东西:

虽然上面的方法可以去掉一些未使用的空间,但对于数据库文件(MDF)来说有一些严重的缺点 - 它会通过分裂索引来损害它们,从而恶化数据库的性能。因此,您需要在收缩命令引起的碎片后重新构建索引。

如果你只想缩小日志文件,可能会想使用 SHRINKFILE。我从 MSDN 上复制了这个例子:

USE AdventureWorks2012;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2012
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2012_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2012
SET RECOVERY FULL;
GO

45
不要冒险手动删除你的LDF文件! 如果你不需要事务文件或想将其缩小到任意大小,请按照以下步骤进行操作:(请注意这将影响您的备份,因此在执行此操作之前一定要确认)
  1. 右键单击数据库
  2. 选择属性
  3. 点击“选项”选项卡。
  4. 将恢复模型设置为SIMPLE
  5. 接下来,选择“文件”选项卡
  6. 现在确保你选择了日志文件并向右滚动。 在“自动增长”标题下,点击点点....
  7. 然后禁用自动增长(这是可选的,并将限制额外的增长)
  8. 然后点击确定并将“初始大小”设置为你希望拥有的大小(我将其设置为20MB)
  9. 单击“确定”保存更改
  10. 然后再次右键单击DB,选择“任务> 收缩> 数据库”,按OK。
  11. 现在比较一下你的文件大小!:)

当你在第9步点击“确定”时,似乎第10步会自动执行。 - Jeff Davis

30

我通过以下步骤完成了这个操作:

  • 分离数据库(包括断开连接)
  • 移除 *.ldf 文件
  • 附加数据库,但移除预期的 *.ldf 文件

我在 SQL 2012 中对 4 个不同的数据库执行了此操作,对于 SQL 2008 应该是相同的。


29
谢谢!我不知道为什么人们倾向于忽略问题并把你当作婴儿对待(例如那些回答“不要这样做,因为它很危险”)。我从客户那里收到了示例和测试数据库,我只需要暂时访问他们的数据。有时他们会有一个40或50 GB的LDF文件!我不关心恢复这个数据库,我只需要在我的硬盘驱动器中摆脱掉这40 GB! - Alexandre M
2
这就是我寻找的答案,也是我来到这个页面的原因。谢谢。 - hina10531

7

如你所见,从日志中删除信息并不是一个好的解决方案。但如果你确定不会损失任何数据,可以将数据库恢复模式更改为简单模式,然后使用

DBCC shrinkdatabase ('这里填写数据库名称')

来清除日志。

最糟糕的做法是直接从磁盘中删除日志文件。如果在服务器停止时存在未完成的事务,那么在重启后这些事务不会回滚,你将得到损坏的数据。


2
dbcc shrinkdatabase是一个过于粗暴的方法。如果你只想缩小一个文件,使用dbcc shrinkfile即可。 - Ben Thul

2

您应该备份事务日志,这样就会有可用空间来收缩它。如果更改为简单模式然后收缩,则会丢失所有事务数据,在恢复事件中这些数据是有用的。


1
也许是,也许不是。这完全取决于数据库等待重新使用日志空间的原因。检查sys.databases中相关数据库的log_reuse_wait_desc列将告诉您答案。 - Ben Thul

1

如果所有数据库都进行了备份,那么在MS SQL服务器中清除所有数据库中的所有ldf文件(事务日志文件)的最佳方法是:

USE MASTER
print '*****************************************'
print '************ Czyścik LDF ****************'
print '*****************************************'

declare
   @isql varchar(2000),
   @dbname varchar(64),
   @logfile varchar(128),
   @recovery_model varchar(64)

   declare c1 cursor for 
   SELECT  d.name, mf.name as logfile, d.recovery_model_desc  --, physical_name AS current_file_location, size
   FROM sys.master_files mf
      inner join sys.databases d
      on mf.database_id = d.database_id
   --where recovery_model_desc <> 'SIMPLE'
   and d.name not in ('master','model','msdb','tempdb') 
   and mf.type_desc = 'LOG'
   and d.state_desc = 'online'   
   open c1
   fetch next from c1 into @dbname, @logfile, @recovery_model
   While @@fetch_status <> -1
      begin

      print '----- OPERATIONS FOR: ' + @dbname + ' ------'

      print 'CURRENT MODEL IS: ' + @recovery_model

      select @isql = 'ALTER DATABASE ' + @dbname + ' SET RECOVERY SIMPLE'
      print @isql
      exec(@isql)
      select @isql='USE ' + @dbname + ' checkpoint'
      print @isql
      exec(@isql)
      select @isql='USE ' + @dbname + ' DBCC SHRINKFILE (' + @logfile + ', 1)'
      print @isql
      exec(@isql)
      select @isql = 'ALTER DATABASE ' + @dbname + ' SET RECOVERY ' + @recovery_model
      print @isql
      exec(@isql)

      fetch next from c1 into @dbname, @logfile, @recovery_model
      end
   close c1
   deallocate c1

这是一段改进的代码,基于: https://www.sqlservercentral.com/Forums/Topic1163961-357-1.aspx

我建议阅读这篇文章: https://learn.microsoft.com/en-us/sql/relational-databases/backup-restore/recovery-models-sql-server

有时候值得在某些数据库上永久启用RECOVERY MODEL = SIMPLE,从而一劳永逸地摆脱日志问题。特别是当我们每天备份数据(或服务器),并且白天的更改从安全角度来看不是关键时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接