0

我有一个.mdf138 GB 的数据库文件和一个 55 GB 的事务日志文件。

恢复模式设置为完全(不需要)。我运行了数据库和事务日志的完整备份。事务日志仍然是 55 GB,没有可用空间来收缩文件。

我通过 SQL Server Management Studio GUI 运行该备份。然后我运行以下命令来尝试强制 trans log 缩小:

BACKUP LOG database WITH TRUNCATE_ONLY
DBCC SHRINKFILE (logfile, TRUNCATEONLY )

日志文件仍为 55 GB。然后我将恢复模式更改为Simple并让它静置几天,但它仍然是 55 GB。我再次尝试了上面的这两个命令,但它仍然没有截断任何内容。

无论我尝试什么,这个日志文件都不会缩小。由于我们根本不需要事务日志,我什至尝试分离数据库、重命名日志文件并重新附加。这也不起作用,因为实际上有 2 个事务日志,并且在尝试在没有日志的情况下重新附加时出现错误。另一个日志文件只有 1 MB,我也尝试将其删除,但也会收到错误消息,说它不是空的。

有什么我想念的,还是我可以尝试的其他东西?

谢谢你的帮助!

4

7 回答 7

2

在我必须缩小事务日志的极少数情况下,我在 SQL Server 2005 上使用的命令与您尝试的命令略有不同:

backup log database with no_log
dbcc shrinkfile (logfile,1)

...with no_log而不是...with truncate_only, 的第二个参数dbcc shrinkfile必须是所需的日志文件的新大小)

为了确保我得到正确的日志文件的名称(并且因为我懒得输入数据库的名称),我使用这个脚本来自动获取数据库和日志文件的名称:

declare @dbname varchar(255)
declare @logfile varchar(255)

select @dbname = db_name()
select @logfile = name from sysfiles where filename like '%.ldf'

backup log @dbname with no_log
dbcc shrinkfile (@logfile,1)

您需要直接在要收缩日志文件的数据库中运行它。
免责声明:我从来没有在一个有多个日志文件的数据库上使用它,比如你的。如果默认情况下发现错误的日志文件,也许您必须更改它。

Simple如果您仍然不需要恢复模式,则可以在运行脚本之前将恢复模式设置为Full

并且您应该在缩小日志后立即进行完整备份。如果您让数据库处于恢复模式
,这一点非常重要Full
(因为收缩日志会破坏日志链,这意味着后续的日志备份是没有用的,直到你进行下一次完整备份)

于 2012-05-10T23:19:48.830 回答
0

尝试设置checkpoint http://msdn.microsoft.com/en-us/library/ms188748.aspx

这会将所有脏页写入磁盘,从当前数据库的缓冲区缓存中刷新日志页,最大限度地减少恢复期间必须前滚的修改数量。它创建一个新的最小恢复日志序列号 (lsn) 并删除该 lsn 之前的所有记录,从而缩小文件。

于 2012-05-10T21:52:41.693 回答
0

“我什至尝试分离数据库,重命名日志文件并重新附加”:日志不是可选组件!立即运行 DBCC CHECKDB 以查看是否导致损坏。如果由于某种原因有未刷新的页面,您将导致损坏。即使不是,你也是在赌博。

SQL Server 日志文件不是信息性文本日志。

如果您不需要日志,请切换到简单模式并缩小日志文件(您已经这样做了)。TRUNCATE_ONLY 已过时,我不知道它是否有任何作用。

查看sys.databases并查看 log_reuse_wait_desc 列中的值。它会告诉你是什么保留了日志。

于 2012-05-10T21:56:28.250 回答
0

首先,您可以将日志文件的初始大小设置得更低吗?如果有人以 55GB 启动它,它可能不会低于这个值。

其次,您可能不需要两个事务日志。第二个将是“活动的”,但在第一个已满之前不会使用。如果您没有限制增长并且仍然有剩余磁盘空间,第一个可能永远不会被填满。

第三,正如@JohnNolan 建议的那样(正如我即将建议的那样),尝试一个检查点,因为这应该允许在简单恢复模型下截断日志。

此外,建议您避免使用TRUNCATE_ONLY.

于 2012-05-10T21:57:52.047 回答
0

这是 ms sql 服务器的问题,但这是解决方案....

要强制截断数据库,请执行以下操作:

  1. 在收缩之前运行完整的数据库备份
  2. 将恢复从完全设置为简单
  3. dbcc 收缩文件
  4. 将恢复设置为完全
  5. 缩小后运行完整的数据库备份

这是强制收缩的代码

 use master
 Alter database dbname set Recovery simple; 

 use dbname
 DBCC SHRINKFILE (dbname_log, 0, TRUNCATEONLY)
 Alter database dbname set Recovery full;

希望这可以帮助。

于 2012-05-11T02:23:46.273 回答
0

我将如何解决这个问题:

1) 从 sys.databases 中选择 log_reuse_wait_desc 其中 name = 'your_db_name'

这将为您提供阻止 VLF 被重用的原因。在缓慢的时期(即当日志没有被大量使用时,这应该是'NONE')。如果您看到其他值,您可能需要进行故障排除。

2)看一下dbcc loginfo的输出。它为您在日志文件中的每个 VLF 返回一行。状态栏告诉您 VLF 是否在使用中。为了缩小日志,您需要将未使用的 VLF 放在文件末尾。您可能必须等待自然活动才能做到这一点。由于 VLF 被用于一种环中,因此未使用的 VLF 最终应该位于文件的末尾。

于 2012-05-11T03:08:07.287 回答
0

使用以下查询:

backup log [dbname] with truncate_only
go
DBCC SHRINKDATABASE ([dbname], 10, TRUNCATEONLY)
go
于 2014-10-27T09:12:37.740 回答