SQL Server 误区:Checkpoint 会将未提交的事务脏页写入磁盘

Cora
Cora
发布时间:2026-10-15 | 4人浏览过
原创

很多人误以为 SQL Server 的 Checkpoint 操作只会把已提交的事务页面刷入磁盘。实际上,无论事务是否已经提交,只要其修改过的数据页处于“脏页”状态且符合刷新条件,都会在 Checkpoint 时被写回磁盘。本文将详细解析 Checkpoint 的工作机制及验证方法。

核心事实:Checkpoint 的职责

误区 #15: Checkpoint 只会将已提交的事务写入磁盘。

这个误区源于对日志和恢复系统缺乏全面了解。事实上,CheckPoint 的核心职责是确保数据库的一致性,具体而言:

  • 通用行为: CheckPoint 会将自上次 CheckPoint 以来所有在内存中改变的页(即“脏页”,Dirty Pages),或者是在上一个 CheckPoint 时读入内存但尚未持久化的脏页,强制写回磁盘。
  • 关键结论: 无论修改这些页的事务是否已经提交,其所影响的脏页都会在 CheckPoint 时写回磁盘。
  • 例外情况: TempDB 是一个例外。由于 TempDB 不需要恢复到故障前的状态,因此在其 CheckPoint 事件周期中并不包含将脏页写回磁盘的步骤。

如何观察 Checkpoint 的工作细节

为了深入理解 CheckPoint 如何在后台工作,可以通过启用特定的跟踪标记(Trace Flags)来查看错误日志中的详细信息。

第1步:启用相关跟踪标记

你需要针对所有线程开启以下两个标记,否则可能无法在错误日志中看到相关信息:

  • 跟踪标记 3502: 当 CheckPoint 开始和结束时,记录相关信息到错误日志。
  • 跟踪标记 3504: 记录 CheckPoint 时将哪些页的信息写回磁盘到错误日志。

使用以下命令全局开启这两个追踪标记:

DBCC TRACEON (3502, 3504, -1);

注意:在生产环境中谨慎使用此类调试级跟踪标记,因其可能产生大量日志写入。

第2步:构建测试环境与触发脏页

下面提供一段完整的代码,用于创建一个测试数据库和表,并生成约 10MB 的脏页,紧接着执行 CheckPoint 来观察结果。

-- 创建测试数据库
CREATE DATABASE CheckpointTest;
GO
USE CheckpointTest;
GO

-- 创建测试表
CREATE TABLE t1 (
    c1 INT IDENTITY,
    c2 CHAR (8000) DEFAULT 'a'
);
GO

-- 创建聚集索引以优化存储
CREATE CLUSTERED INDEX t1c1 ON t1 (c1);
GO

-- 关闭计数消息以提高性能
SET NOCOUNT ON;
GO

-- 先执行一次Checkpoint清理环境
CHECKPOINT;
GO

-- 开启跟踪标记以监控Checkpoint行为
DBCC TRACEON (3502, 3504, -1);
GO

第3步:执行未提交事务并触发CheckPoint

启动一个事务,插入大量数据产生脏页,然后立即执行 CheckPoint,但不提交事务。这是验证上述理论的关键步骤。

BEGIN TRAN;
GO

-- 插入1280行数据,每行约占8KB,总计约10MB脏页
INSERT INTO t1 DEFAULT VALUES;
GO 1280

-- 执行Checkpoint
CHECKPOINT;
GO

结果分析

执行上述代码后,查看 SQL Server 的错误日志,你会发现明确的日志输出。2012-10-17_092031

从日志中可以清楚地看出,尽管事务尚未 COMMIT(即未提交),但相关的脏页依然已经被 CheckPoint 进程强制写入了磁盘文件。这证明了 CheckPoint 的主要目标是保证检查点之前已修改数据的物理一致性,而非逻辑事务的提交状态。

简要总结

SQL Server 的 Checkpoint 机制旨在减少故障恢复时间。它不负责判断事务是否逻辑上完成,而是负责将内存中所有符合条件的“脏页”同步到磁盘。理解这一点对于数据库恢复原理的学习至关重要。以上就是关于 SQL Server Checkpoint 机制的详细解析,更多关于数据库内部原理的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表