为什么我的使用简单恢复模式的数据库有这么大的事务日志?

Jes*_*lam 2 sql-server transaction-log recovery-model sql-server-2017

不重复:

原因:我的日志不大,但是是空的。它很大,但正在使用中。


问题

我有一个小型数据库 (100 MB),它全天都会受到大量小型事务性工作负载的影响。尽管我似乎了解如何限制它,但我已经看到事务日志继续增长。显然我错过了一些东西。

  • 数据库处于简单恢复模式(我不能保证它在第一次创建时没有处于完全状态,但它从未处于完全负载状态)。

  • DBCC SQLPERF(Logspace) 说:

| Log Size (MB) | Log Space Used (%) | Status
--------------------------------------------
| 927.2422      | 94.72562           | 0
Run Code Online (Sandbox Code Playgroud)
  • DBCC LOGINFO 说:

有39行(VLF)进行,所有这些都具有Status2

  • DBCC opentran 说:

最旧的活动事务:
SPID:51
名称:user_transaction
开始时间:2019 年 3 月 11 日晚上 7:27

注意:鉴于我的服务器时间,此事务大约有五分钟的历史。


我不明白为什么当我的应用程序只创建 - 最多 - 大约六个短期交易时,每个 VLF 都在使用中,尽管非常频繁。

我尝试终止连接到该数据库的唯一应用程序进程,但它没有释放事务日志。

解决方法

我做了一个完整备份只是为了解决这个问题,它释放了整个日志空间......所以......我不知道。我得看看它是否会再次过度生长。

Jos*_*ell 5

遇到此类问题的第一站应该始终是以下查询:

SELECT log_reuse_wait, log_reuse_wait_desc
FROM sys.databases 
WHERE [name] = 'YourDatabaseName';
Run Code Online (Sandbox Code Playgroud)

sys.databases文档:

从最后一个检查点开始,事务日志空间的重用当前正在等待以下之一。

该页面上有一个可能值的列表,以及此处不同值的大量附加详细信息:事务日志 (SQL Server) - 可以延迟日志截断的因素

如果您的服务器不是很忙,则可能已经有一段时间没有自动CHECKPOINT运行了。这是在内存中修改数据页后将数据页写入磁盘的过程。事务日志中的操作在成功刷新到数据文件之前无法被覆盖,因此您最终会得到 log_reuse_wait 的1 = Checkpoint.

由于您使用的是简单恢复模型,这似乎是更有可能的罪魁祸首之一(因为您排除了长时间运行的事务)。运行完整的数据库备份会导致 aCHECKPOINT运行,这可能是导致运行备份后日志文件最终为您清除的原因。来自Database Checkpoints (SQL Server),特别是关于“内部”检查点类型:

由各种服务器操作(例如备份和数据库快照创建)发出,以确保磁盘映像与日志的当前状态匹配。