Sql server 日志文件上的DBCC SHRINKFILE即使在将日志备份到磁盘后也不会减小大小

Sql server 日志文件上的DBCC SHRINKFILE即使在将日志备份到磁盘后也不会减小大小,sql-server,backup,transaction-log,dbcc,Sql Server,Backup,Transaction Log,Dbcc,我有一个数据库,[My DB],其中包含以下信息: SQL Server 2008 中密度纤维板尺寸:30 GB LDF大小:67 GB 我想尽可能地缩小日志文件,所以我开始研究如何做到这一点。警告:我不是DBA(甚至不是接近DBA的),我一直在通过这个任务按感觉前进 首先,我进入了SSM、DB属性、文件,并将初始大小(MB)值编辑为10。这将日志文件减少到62 GB(与我输入的10 MB不完全相同)。所以,我附加了SQL分析器,看到正在调用DBCC SHRINKFILE。然后,我将该命令输入到

我有一个数据库,[My DB],其中包含以下信息:
SQL Server 2008
中密度纤维板尺寸:30 GB
LDF大小:67 GB

我想尽可能地缩小日志文件,所以我开始研究如何做到这一点。警告:我不是DBA(甚至不是接近DBA的),我一直在通过这个任务按感觉前进

首先,我进入了SSM、DB属性、文件,并将初始大小(MB)值编辑为10。这将日志文件减少到62 GB(与我输入的10 MB不完全相同)。所以,我附加了SQL分析器,看到正在调用DBCC SHRINKFILE。然后,我将该命令输入到查询编辑器中,下面是结果

DBCC SHRINKFILE (N'My DB_Log' , 10)
结果是:

Cannot shrink log file 2 (My DB_Log) because the logical log file located at the end of the file is in use.
DbId   FileId      CurrentSize MinimumSize UsedPages   EstimatedPages
------ ----------- ----------- ----------- ----------- --------------
8      2           8044104     12800       8044104     12800

(1 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your system administrator.
然后我做了一些研究,发现:

这意味着我需要在收缩文件之前备份日志文件,以便释放虚拟日志文件,收缩文件可以完成它的工作-我不知道这意味着什么。。。我只是在这里转述:)

因此,我想我应该尝试备份日志文件,然后执行DBCC SHRINKFILE(我将新的日志文件大小更改为12800,因为这是在上一个DBCC SHRINKFILE命令的输出中标识的最小大小)

结果与第一次循环相同。我只能将日志文件降至62 GB


我不确定我做错了什么以及下一步应该尝试什么。

除了您已经采取的步骤外,您还需要将恢复模式设置为“简单”,然后才能收缩日志

这不是生产系统的推荐做法。。。您将无法从以前的备份/日志文件恢复到某个时间点


有关示例和说明,请参见本msdn页面上的示例B

保罗·兰德尔在他的博客上对这个问题进行了精彩的讨论:

试试这个

ALTER DATABASE XXXX  SET RECOVERY SIMPLE

use XXXX

declare @log_File_Name varchar(200) 

select @log_File_Name  = name from sysfiles where filename like '%LDF'

declare @i int = FILE_IDEX ( @log_File_Name)

dbcc shrinkfile ( @i , 50) 

感谢@user2630576和@Ed.S

以下措施起到了积极作用:

BACKUP LOG [database] TO DISK = 'D:\database.bak'
GO

ALTER DATABASE [database] SET RECOVERY SIMPLE

use [database]

declare @log_File_Name varchar(200)

select @log_File_Name = name from sysfiles where filename like '%LDF'

declare @i int = FILE_IDEX ( @log_File_Name)

dbcc shrinkfile ( @i , 50)

ALTER DATABASE [database] SET RECOVERY FULL

好的,这里有一个减少事务文件物理大小的解决方案,但不将恢复模式更改为simple

在数据库中,使用以下查询找到日志文件的文件\u id

SELECT * FROM sys.database_files;
在我的实例中,日志文件是file_id 2。现在我们要定位正在使用的虚拟日志,并使用以下命令执行此操作

DBCC LOGINFO;
在这里,通过查看状态是2(正在使用)还是0(可用),可以查看是否有任何虚拟日志正在使用。收缩文件时,将从文件末尾开始物理删除空虚拟日志,直到其达到第一个已使用状态。这就是为什么收缩事务日志文件有时会收缩一部分,但不会删除所有可用的虚拟日志

如果您注意到0之后出现状态2,这将阻止收缩完全收缩文件。要解决这个问题,请执行另一个事务日志备份,并立即运行这些命令,提供上面找到的文件\u id,以及您希望日志文件减小到的大小

-- DBCC SHRINKFILE (file_id, LogSize_MB)
DBCC SHRINKFILE (2, 100);
DBCC LOGINFO;

这将显示虚拟日志文件分配,希望您会注意到它有所减少。由于虚拟日志文件并非总是按顺序分配,您可能需要备份事务日志几次,然后再次运行最后一次查询;但我通常可以在一两次备份中缩减它。

我在sql server 2008 R2上使用此脚本

USE [db_name]

ALTER DATABASE [db_name] SET RECOVERY SIMPLE WITH NO_WAIT

DBCC SHRINKFILE([log_file_name]/log_file_number, wanted_size)

ALTER DATABASE [db_name] SET RECOVERY FULL WITH NO_WAIT

我尝试了很多方法,但都奏效了

示例代码在中提供


我通过进行完整的事务备份解决了这个问题。有时,备份过程没有完成,这也是.ldf文件没有收缩的原因之一。试试这个。这对我很有效。

出于好奇,有没有办法通过SSMS UI查看恢复模式?我查看了DB属性,但没有看到它。最接近的是显示Recovery/PageVerify值的Properties/Options页面。找到它-它不在“其他选项”列表中。它位于页面顶部-三个下拉列表之一。我建议运行这个查询:从sys.databases中选择recovery\u model\u desc,其中name='database name'谢谢。更改恢复模式是关键:)为了防止这种情况再次发生,您应该运行日志备份或将恢复模式设置为“简单”。我的问题是复制/镜像设置已暂停—如果sql认为需要它们进行复制,它似乎不会收缩TLOG。这可能不会成为很多人的问题,但可能会对一些人有所帮助。效果很好。备份99%的可用日志只需一秒钟,文件立即从22000MB增加到200MB。这应该被标记为正确答案。我很感激你提供的背景信息。不过,我还是被卡住了,因为我认为你的解决方案归根结底是原始海报尝试过但无法实现的解决方案。您的解决方案基本上是运行“备份日志…转到DBCC SHRINKFILE…”多次,直到它工作为止吗?我试过好几次都没有成功,而OP似乎也试过,但都没有成功。我只是想澄清一下,看看你的回答中是否遗漏了什么。更新:我的问题是,暂停的复制/镜像安装程序正在锁定tlog。可能是一个小的边缘大小写。@pettys是的,如果你想将文件缩小到尽可能小的大小,你必须一次备份、缩小、备份和缩小。原因(我认为是有意的)是,收缩只会将日志文件的大小减小到上次备份后“使用过的页面”的大小;可能是为了最大限度地减少日志文件的增长需求,这对于定期加载和备份的生产环境非常有用。上面试图演示和调试这一点。如果日志文件中有“0”,则可以进一步缩小它。如果没有,那么释放备份日志的页面可能会有问题。如果你这样做,你就破坏了事务日志备份链——如果之后发生灾难
USE [db_name]

ALTER DATABASE [db_name] SET RECOVERY SIMPLE WITH NO_WAIT

DBCC SHRINKFILE([log_file_name]/log_file_number, wanted_size)

ALTER DATABASE [db_name] SET RECOVERY FULL WITH NO_WAIT
USE DBName;  
GO  
-- Truncate the log by changing the database recovery model to SIMPLE.  
ALTER DATABASE DBName  
SET RECOVERY SIMPLE;  
GO  
-- Shrink the truncated log file to 1 MB.  
DBCC SHRINKFILE (DBName_log, 1);  --File name SELECT * FROM sys.database_files; query to get the file name
GO  
-- Reset the database recovery model.  
ALTER DATABASE DBName  
SET RECOVERY FULL;  
GO