ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SQL Server 模拟checksum检测错误

2026/9/3 16:57:50 拓冰建站 浏览量
SQL Server 模拟checksum检测错误 要模拟备份时CHECKSUM检测到错误并中断最有效的方法是直接修改数据库数据页的底层二进制数据即人为制造物理损坏/Page Corruption。在 SQL Server 中无法通过常规的UPDATE语句破坏页面校验和因为引擎会自动重新计算。我们需要使用未公开的危险命令DBCC WRITEPAGE来直接篡改磁盘上的字节。以下是完整的模拟步骤请务必在独立的测试数据库中操作绝对不能在生产环境运行第一步准备测试数据库和表首先创建一个名为TestVerify的干净数据库并写入一条测试数据。-- 1. 创建测试数据库 CREATE DATABASE TestVerify; GO USE TestVerify; GO -- 2. 设置页面校验和为 CHECKSUM默认通常也是这个 ALTER DATABASE TestVerify SET PAGE_VERIFY CHECKSUM; GO -- 3. 创建一张简单的表并插入数据 CREATE TABLE TestTable (ID INT IDENTITY(1,1), Name VARCHAR(100)); INSERT INTO TestTable (Name) VALUES (Row_To_Be_Corrupted); GO第二步找出数据所在的物理页面Page ID我们需要知道数据存放在哪个数据页上以便对其进行精准破坏。-- 使用 DBCC IND 查看表的页面分配 -- 参数: (数据库名, 表名, 1代表聚集索引或堆) DBCC IND (TestVerify, TestTable, 1); GO运行后在结果集中找到PageType 1的那一行1 代表数据页 Data Page。记住这一行的PageFID文件 ID通常是 1和PagePID页面 ID例如是 240。直接篡改数据行的内容比如把字母 R 改掉-- 1. 开启跟踪标记允许将 DBCC 的结果输出到 SSMS 消息窗口 DBCC TRACEON (3604); GO -- 2. 查看页面内容 -- 参数: (数据库名, 文件ID, 页面ID, 输出格式) -- 输出格式 0 代表只打印页面头部1 代表打印每行的十六进制和文本对照推荐 DBCC PAGE (TestVerify, 1, 240, 1); GO原值分析在数据行的内存镜像中十六进制的52代表大写字母R即Row的开头。寻找绝对偏移量OffsetSlot 0的起始绝对偏移量是0x60十进制的96。从3000...开始数十六进制的52位于第 16 个字节的位置从 0 开始算偏移是 15。因此字母 R 在整个页面中的绝对偏移量是96 15 111。你想改成0x33的话命令应该这样写第三步使用 DBCC WRITEPAGE 故意破坏页面结构现在我们把数据库设为单用户模式然后直接向这个页面写入错误的垃圾数据从而破坏它的 Checksum 校验。注意请将下面代码中的312替换为你上一步实际查到的PagePID。-- 切换单用户模式 ALTER DATABASE TestVerify SET SINGLE_USER WITH ROLLBACK IMMEDIATE; GO DBCC TRACEON (3604, 2588); GO -- 将偏移量设为 111把字母 R (0x52) 强行篡改为 0x33字符 3 DBCC WRITEPAGE (TestVerify, 1, 240, 111, 1, 0x33,1); GO DBCC TRACEOFF (3604, 2588); GO -- 恢复多用户 ALTER DATABASE TestVerify SET MULTI_USER; GO-- 1. 开启跟踪标记允许将 DBCC 的结果输出到 SSMS 消息窗口 DBCC TRACEON (3604); GO -- 2. 查看页面内容 -- 参数: (数据库名, 文件ID, 页面ID, 输出格式) -- 输出格式 0 代表只打印页面头部1 代表打印每行的十六进制和文本对照推荐 DBCC PAGE (TestVerify, 1, 240, 1); GO第四步测试备份见证 CHECKSUM 报错 现在我们运行带有WITH CHECKSUM的备份命令。由于磁盘上的页面已被破坏备份会立刻中断并报出物理损坏的错误。BACKUP DATABASE [TestVerify] TO DISK NS:\tmp\TestVerify.bak WITH NOFORMAT, INIT, NAME NTestVerify-Full Database Backup, SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS 10, CHECKSUM GOExpected Output (预期错误信息)你会看到类似下面的报错提示遇到了 输入/输出(I/O)错误并且明确指出了 Checksum 不匹配通过这个实验你可以直观地看到CHECKSUM是如何在第一时间内拦截坏数据的。如果你想进一步了解当遇到这种备份报错时应该通过什么步骤去尝试挽救或修复数据库请告诉我