首页 > 解决方案 > SQL Server 中的异常 CHECKPOINT 行为

问题描述

我希望就 SQL Server 中奇怪的检查点行为的原因获得一些意见。

我有一个采用 SIMPLE 恢复模型的数据库,大小从 10 GB 开始。该数据库位于 SQL Server 2017 实例上,并配置为使用 target_recovery_time_in_seconds 设置为 60 的间接检查点。

我们有触发事务日志百分比使用率 (70%) 的警报,这通常是内部 CHECKPOINT 发生的时候。然后,随着事务日志继续增长,我们继续收到警报,最终记录到 99% 已满,但没有进一步增长。

sys.databases 中的 log_reuse_wait_desc 列显示 ACTIVE TRANSACTION 是上次尝试日志截断失败的原因。我确认没有使用接近所有相关 DMV 运行的活动交易。

发出 CHECKPOINT 手动清除 wait_desc 并截断日志。

我的理论是,在最后一次尝试日志截断时,数据库有一个活动事务,无论是在 70% 的日志使用率被破坏时,还是在达到要刷新到磁盘的目标脏缓冲区之后。在任何一种情况下,此时都有一个活动事务阻止了日志截断。由于最后一个检查点,由于没有达到脏缓冲区阈值而导致没有进一步检查点尝试的活动很少,因此即使现在没有活动的事务日志截断也不会发生,直到发出 CHECKPOINT。

我打算放置跟踪标志 3502 以查看该事务应该运行时的检查点活动。

有没有人遇到过这种行为,或者知道当事务日志使用率超过 70% 时,SQL Server 是否为运行检查点配置了回退,即使日志继续填满?

非常感谢!

标签: sqlsql-serversql-server-2016sql-server-2017

解决方案


正如@sepupic 所指出的,发出检查点的 70% 日志空间使用率是自动检查点的特征,而不是内部检查点(请参阅问题评论)。

这种被注意到的行为的简单原因是间接检查点会在活动事务继续执行时响应脏页阈值违规。活动事务阻止了检查点发生日志截断,因此事务日志继续增长。

在最后一个间接检查点和之前的活动事务(防止日志截断)完成之间,没有足够的脏页来触发间接检查点的发生。

因此,为什么即使在调查后没有发现活动事务并且日志文件使用被发出的手动 CHECKPOINT 命令立即清除时,最后一个 log_reuse_wait_desc 仍然是 ACTIVE TRANSACTION。


推荐阅读