SQL Server 2008日志将不会截断 我认为自己是一个非常有经验的SQL人。但我没有做到这两件事: 减少已分配日志的大小

SQL Server 2008日志将不会截断 我认为自己是一个非常有经验的SQL人。但我没有做到这两件事: 减少已分配日志的大小,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,截断日志 DBCC sqlperf(日志空间) 返回: Database Name Log Size (MB) Log Space Used (%) Status ByBox 1964.25 30.0657 0 以下内容不适用于SQL 2008 DUMP TRANSACTION ByBox WITH TRUNCATE_ONLY 运行以下命令也不会产生任何效果 DBCC SHRINKFILE ('ByBox_1_Log' , 1) DBCC sh

截断日志

DBCC sqlperf(日志空间)

返回:

Database Name   Log Size (MB)   Log Space Used (%)  Status
ByBox       1964.25     30.0657         0
以下内容不适用于SQL 2008

DUMP TRANSACTION ByBox WITH TRUNCATE_ONLY
运行以下命令也不会产生任何效果

DBCC SHRINKFILE ('ByBox_1_Log' , 1)
DBCC shrinkdatabase(N'bybox')
我试过备份。我还尝试将数据库的属性--“Recover Model”同时设置为“FULL”和“SIMPLE”,并将上述所有属性组合在一起。我还尝试将兼容性设置为SQLServer2005(我使用此设置是因为我希望与生产服务器匹配)和SQLServer2008

不管我怎么做,日志仍保持在1964.25MB,使用率为30%,而且还在增长

我希望日志恢复到接近0%,并将日志文件大小减少到100MB,这就足够了。我的数据库一定恨我;它只是忽略了我要求它做的关于日志的所有事情

另请注意。生产数据库有相当多的复制表,当我使用以下方法在开发箱上执行恢复时,我会关闭这些复制表:

-- Clear out pending replication stuff
exec sp_removedbreplication
go
EXEC sp_repldone @xactid = NULL, @xact_segno = NULL,
     @numtrans = 0, @time = 0, @reset = 1
go
USE master
GO

EXEC sp_addumpdevice 'disk', 'ByBoxData', N'C:\<path here>\bybox.bak'

-- Create a logical backup device, ByBoxLog.
EXEC sp_addumpdevice 'disk', 'ByBoxLog', N'C:\<path here>\bybox_log.bak'

-- Back up the full bybox database.
BACKUP DATABASE bybox TO ByBoxData

-- Back up the bybox log.
BACKUP LOG bybox TO ByBoxLog
尝试:

SELECT log_reuse_wait, log_reuse_wait_desc
FROM sys.databases
WHERE NAME='bybox'
返回

log_reuse_wait  log_reuse_wait_desc
0   NOTHING
我如何解决这个问题


查看恢复模型并将其设置为“完全”,我尝试了以下方法:

-- Clear out pending replication stuff
exec sp_removedbreplication
go
EXEC sp_repldone @xactid = NULL, @xact_segno = NULL,
     @numtrans = 0, @time = 0, @reset = 1
go
USE master
GO

EXEC sp_addumpdevice 'disk', 'ByBoxData', N'C:\<path here>\bybox.bak'

-- Create a logical backup device, ByBoxLog.
EXEC sp_addumpdevice 'disk', 'ByBoxLog', N'C:\<path here>\bybox_log.bak'

-- Back up the full bybox database.
BACKUP DATABASE bybox TO ByBoxData

-- Back up the bybox log.
BACKUP LOG bybox TO ByBoxLog
太好了!但事实并非如此

DBCC SHRINKFILE('ByBox_1_Log',1)现在返回

DbId    FileId  CurrentSize MinimumSize UsedPages   EstimatedPages
7   2   251425  251425  251424  251424
DBCC SQLPERF(日志空间)仍然报告了30%的使用率


我想我可能不得不承认SQL Server 2008中很可能存在漏洞,或者我的日志文件已以某种方式损坏。然而,我的数据库工作状态良好,这让我觉得有一个bug(一想到就不寒而栗)。

我知道你的意思-SQL server可能有点让人恼火。下面是一些要尝试的示例代码。本质上,它会截断日志文件,然后尝试收缩该文件。让我知道它是如何工作的。还有一件事……你不会有未提交的交易,是吗

Use YourDatabase
GO

DBCC sqlperf(logspace)  -- Get a "before" snapshot
GO  

BACKUP LOG BSDIV12Update WITH TRUNCATE_ONLY;  -- Truncate the log file, don't keep a backup
GO

DBCC SHRINKFILE(YourDataBaseFileName_log, 2);  -- Now re-shrink (use the LOG file name as found in Properties / Files.  Note that I didn't quote mine).
GO

DBCC sqlperf(logspace)  -- Get an "after" snapshot
GO

更新:Simon注意到备份命令出错。当我早些时候回答时,我没有意识到SQL Server 2008中已经停止了“仅截断”。经过一番研究后,收缩日志文件的建议步骤是:(a)将恢复模型更改为Simple,然后(b)如上所述使用DBCC ShrinkFile收缩文件。不幸的是,您提到您已经尝试将恢复模型设置为Simple,因此我假设您随后也运行了DBCC Shrinkfile。这是正确的吗?请让我知道。

这可能是一种痛苦,可能有很多事情。您应该确保的第一件事是没有“卡住”的交易。如果事务从未关闭,则无法收缩日志。运行“DBCC OPENTRAN”以查找运行时间最长的事务

此外,请确保重新组织(我认为这是正确的术语),并在收缩之前将所有内容移到文件的开头。

尝试运行

DBCC OPENTRAN

检查是否有任何打开的事务。

我一直讨厌SQL Server处理日志文件物理收缩的方式。请注意,我一直都是通过Enterprise Manager/SQL Server Management Studio来完成这项工作的,但似乎在收缩/截断日志文件时,日志文件的物理大小不会减小,直到对数据库的数据文件进行完全备份,然后再次备份日志文件。我无法确定确切的模式,但你可以试着看看确切的顺序是什么。但是,它总是涉及对数据文件进行完整备份。

我终于得出结论,SQLServer2008中存在一个bug

我已经尝试了一切,我能想到的每一个组合。我备份了数据库,删除了它,重新创建了它,恢复了它。完全相同的问题

我还跑了:

DBCC CHECKDB
DBCC UPDATEUSAGE (bybox)
一切正常


我所能说的就是开始下一个service pack。

找到了解决方案

我向数据库添加了大量数据,因此日志被迫展开。然后,我删除了不需要的数据,以恢复数据库的状态

备份和瞧,一个完美的0%日志

因此,解决方案是使日志扩展。

我发现(MSDN)

以下示例将AdventureWorks数据库中的日志文件压缩为1MB。要允许
DBCC SHRINKFILE
命令收缩文件,首先通过将数据库恢复模型设置为SIMPLE来截断文件

USE AdventureWorks;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks
SET RECOVERY FULL;
GO
注意更改恢复模式的影响 现在,对于所有您制作考虑使用脚本的人来说,还有一个发人深省的想法:

在将恢复模式从完全更改为简单之前。。。如果您处于开发/环境中,则无需担心。但是,如果您所处的生产环境中有责任确保在发生问题时完全恢复数据,您可能需要仔细了解BOL对此的看法(请参见“管理数据库”->“事务日志管理”->“恢复模型和事务日志管理”下的BOL):

可以随时将数据库切换到另一个恢复模型。然而,从简单的恢复模式转变过来是不寻常的。请注意,如果在大容量操作期间切换到完全恢复模式,则大容量操作的日志记录将从最小日志记录更改为完全日志记录,反之亦然

从简单恢复模式切换后

如果从完整或大容量日志恢复模式切换到简单恢复模式,则会中断备份日志链。因此,我们强烈建议您在切换之前立即备份日志,这样可以将数据库恢复到该点。切换后,您需要定期进行数据备份,以保护数据并截断事务日志的非活动部分

切换到简单恢复模式后

USE DatabaseName
GO
-- Truncate the Transaction log
ALTER DATABASE DatabaseName SET RECOVERY SIMPLE
CHECKPOINT
ALTER DATABASE DatabaseName SET RECOVERY FULL
GO
-- Shrink the Transaction Log as recommended my Microsoft.

DBCC SHRINKFILE ('database_txlogfilelogicalname', [n -size to shrink in MBytes])
GO
 -- Pass the freed pages back to OS control.
DBCC SHRINKDATABASE (DatabaseName, TRUNCATEONLY)
GO
-- Tidy up the pages after shrink
DBCC UPDATEUSAGE (0);
GO
-- IF Required but not essential
-- Force to update all tables statistics
exec sp_updatestats
GO
SELECT name, log_reuse_wait, log_reuse_wait_desc FROM sys.databases