如果我停止SQL服务器,然后删除数据库的.LDF文件(事务日志文件),会发生什么?数据库会被标记为可疑状态还是SQL服务器会自动创建一个新的?SQL Server 2008 R2
我的.LDF文件太大了,该如何管理呢?可以收缩它或删除它吗?请在查询表单中提供建议。
如果我停止SQL服务器,然后删除数据库的.LDF文件(事务日志文件),会发生什么?数据库会被标记为可疑状态还是SQL服务器会自动创建一个新的?SQL Server 2008 R2
我的.LDF文件太大了,该如何管理呢?可以收缩它或删除它吗?请在查询表单中提供建议。
不要删除任何数据库文件,因为这可能会严重损坏您的数据库!
如果磁盘空间不足,您可以将数据库分成多个部分。这可以在数据库的属性中完成。因此,您可以将数据库的每个部分放入不同的存储卷中。
如果您将恢复模式从完整模式更改为简单模式,则还可以收缩事务日志文件,使用以下命令:
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
我通过以下步骤完成了这个操作:
我在 SQL 2012 中对 4 个不同的数据库执行了此操作,对于 SQL 2008 应该是相同的。
如你所见,从日志中删除信息并不是一个好的解决方案。但如果你确定不会损失任何数据,可以将数据库恢复模式更改为简单模式,然后使用
DBCC shrinkdatabase ('这里填写数据库名称')
来清除日志。
最糟糕的做法是直接从磁盘中删除日志文件。如果在服务器停止时存在未完成的事务,那么在重启后这些事务不会回滚,你将得到损坏的数据。
您应该备份事务日志,这样就会有可用空间来收缩它。如果更改为简单模式然后收缩,则会丢失所有事务数据,在恢复事件中这些数据是有用的。
如果所有数据库都进行了备份,那么在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,从而一劳永逸地摆脱日志问题。特别是当我们每天备份数据(或服务器),并且白天的更改从安全角度来看不是关键时。