我有一个由大约 50 个客户端通过 TCP 上的 TDS 访问的数据库,这似乎没有释放日志空间。进程数保持在预期的 50 个左右,其中一些进程的寿命很长(> 120 天)。
数据库现在有 40 GB 的日志空间(它只有 14 GB 数据),39 GB 空闲空间。由于驱动器的空间限制,我想缩小到更合理的东西(10gb-ish)。当我执行DBCC SHRINKFILE('db_log', 10000)
时,它返回一个日志末尾正在使用的错误。
为了自由访问日志末尾,我尝试使用以下命令将数据库置于单用户模式:
ALTER DATABASE db SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE db SET MULTI_USER
GO
但脚本返回重复数百次的以下消息:
Nonqualified transactions are being rolled back. Estimated rollback completion: 100%.
这让我相信在某个地方,我留下了一些未提交的交易。我不知道有任何过程会故意一次打开这么多交易,所以我认为它们必须随着时间的推移而累积,永远不会被关闭。
问题:我如何找到有问题的进程或脚本,或者为什么没有发布日志?
sys.dm_tran_active_transactions
显示合理的 18 笔交易,目的可理解。 sp_who
仅显示我知道的过程。
SQL 服务器版本:
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
Apr 2 2010 15:48:46
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)
服务器版本:
Windows Server 2008 R2 x64 - 数据中心 4 个 vCPU,16GB 内存,数据和日志直通磁盘,操作系统磁盘是 VHD
Hyper-V(Windows Server 2008 R2 SP1 x64 Datacenter)双 Intel X5650(6 核,12 线程,2.67GHz)72 GB 内存
Hypervisor 只有三个虚拟机,并没有显示出很高的资源使用率。SQL Server VM 显示约 40% 的 CPU 负载不足和 99% 的缓存命中。
有一个 SQL 命令将显示 OPEN 事务。(DBCC OPENTRAN)
http://msdn.microsoft.com/en-us/library/ms182792.aspx
显示有关指定数据库中最旧的活动事务以及最旧的分布式和非分布式复制事务(如果有)的信息。仅当存在活动事务或数据库包含复制信息时才会显示结果
无论出于何种原因,似乎没有任何东西保持日志文件处于打开状态。通过运行多个日志备份 (>10),日志的结尾被释放并且可能发生收缩。不知道为什么......但它奏效了。
如果我正确理解您的问题,您有一个 40Gb 的事务日志和 39Gb 的免费空间吗?日志是一个循环结构,由较小的虚拟日志文件组成。每次 VLF 已满时,SQL 都会开始使用下一个 VLF。(不一定与文件中 VLF 的顺序相同)。当您收缩日志文件时,它会从日志的 END 释放可用空间。如果日志的活动部分位于末尾,则无法释放空间,如果它位于中间某处,则您只能回收一些空间。DBCC LOGINFO 将向您显示日志中的所有 VLF 以及显示该 VLF 当前包含任何活动日志的状态。我相信状态 2 是活动的,而 0 是非活动的。如果需要,我相信谷歌可以提供更多信息。
如果您的问题只是活动部分当前位于末尾,那么您最好的选择就是等到它再次滚动到开头,然后缩小日志。这可能需要相当长的时间,请耐心等待。它会到达那里。
还要记住,如果 VLF 的任何部分当前处于活动状态,则整个 VLF 将保持活动状态。
但是,您应该监视日志文件的大小,如果它再次意外增长,那么您需要对原因进行一些调查。您应该避免不必要地缩小日志文件,当它再次增长时会降低性能。
有关 VLF 的更多信息,请参阅此处的 Kimberly Tripps 博客文章。