不常见的 824 严重错误

问题描述

  • SQL Server 出现的“消息 824,级别 24”是一个严重的错误(级别24表示系统级别的致命错误),意味着 SQL Server 虽然在操作系统层面成功读取了数据页,但页面内部的数据校验和不匹配,页面已损坏。由于824错误通常由硬件引起,即使修复了数据库,若硬件问题不解决,损坏还会再次发生。
执行语句:select top 100 * from xxx where id > 201405

消息 824,级别 24,状态 2,第 1 行
SQL Server 检测到基于一致性的逻辑 I/O 错误 pageid 不正确(应为 3:1774574,但实际为480:1)。
在文件 'd:\xxx.mdf' 中、偏移量为 0x00000362944000 的位置对数据库 ID 7 中的页 (3:1774574) 执行读取期间,发生了该错误。

解决方案

  • 针对 824 错误,以修复 WSS_Content 库为例,DBCC 修复过程如下:

注1:针对 3.7 TB 的大库执行 DBCC CHECKDB ('WSS_Content') WITH TABLOCK, ALL_ERRORMSGS 耗时 06:08:16

注2:dbcc checkdb 过程不会导致日志变大,不会额外占用磁盘空间,不会破坏日志链;

--.1.先备份一下(如果还可以备份的话)
BACKUP DATABASE WSS_Content TO DISK = 'D:\WSS_Content.20160815.bak' WITH COMPRESSION,STATS=1

--.2.建议修复前后,记录下表行数用作对比
--.由于sp_spaceused获取行数不准确,建议先执行updateusage以更新统计信息.
USE WSS_Content
GO 
DBCC UPDATEUSAGE('WSS_Content')
GO 
IF OBJECT_ID('tempdb..#tb', 'U') <> 0 
DROP TABLE #tb 
CREATE TABLE #tb(
  name varchar(200),
  rows bigint,
  reserved varchar(200),
  data varchar(200),
  index_size varchar(200),
  unused varchar(200)
  ); 
DECLARE @sql varchar(max) 
SET @sql = 'use ' +DB_NAME()+ CHAR(10) 
    + 'exec sp_msforeachtable ''
    declare @tbname sysname = ''''?'''';
    insert into #tb execute sp_spaceused @tbname;'' ' 
EXECUTE(@sql) 
SELECT name,rows FROM #tb ORDER BY rows DESC 

--.若仅仅检查表
-- DBCC CHECKTABLE ('AccountTransaction')

--.3.先设置为单用户模式(否则设置紧急模式前要先杀连接)
ALTER DATABASE WSS_Content SET SINGLE_USER WITH ROLLBACK IMMEDIATE

--.4.再设置为紧急模式
ALTER DATABASE WSS_Content SET EMERGENCY

--.5.1.先快速检查数据库的一致性(3.7 TB的db耗时05:09:01)
DBCC CHECKDB ('WSS_Content') WITH TABLOCK, PHYSICAL_ONLY, ALL_ERRORMSGS

--.新开一个query窗口查看dbcc进度
SELECT percent_complete,* FROM sys.dm_exec_requests WHERE command LIKE '%dbcc%'

--.5.2.再对数据库执行全面检查(3.7 TB的db耗时06:08:16)
DBCC CHECKDB ('WSS_Content') WITH TABLOCK, ALL_ERRORMSGS

--.5.x.先执行不会丢失数据的修复(看运气)(紧急模式不支持此级别的修复).
-- ALTER DATABASE WSS_Content SET ONLINE; DBCC CHECKDB ('WSS_Content', REPAIR_REBUILD) WITH ALL_ERRORMSGS

--.5.x.最坏情况下修复db,允许数据丢失,耗时较久...修复前后记录一下存在一致性错误的表的行数,以做对比...
-- exec sp_spaceused 'DocStreams'
-- DBCC CHECKDB ('WSS_Content', REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS

--.6.再改回多用户模式
ALTER DATABASE WSS_Content SET MULTI_USER

--.7.最后取消紧急模式(若先改回多用户模式会有访问进来)
ALTER DATABASE WSS_Content SET ONLINE

其他类似案例

  • 案例1:2026.07.22 对某个 86992MB 的库(数据7688MB、日志79304MB)执行 backup database 或 backup log 均报错如下:
消息 3049,级别 16,状态 1,第 1 行
BACKUP 操作检测到数据库日志损坏。有关详细信息,请查看错误日志。
  • 尝试执行 dbcc checkdb('mydb') with physical_only 全程无锁,cpu 低于 3%,耗时 00:04:49,没有错误,但执行 backup仍报错
  • 尝试执行 dbcc checkdb('mydb') with all_errormsgs 全程无锁,cpu 低于 3%,耗时 00:05:42,没有错误,但执行 backup仍报错
  • 解决:考虑到错误信息提到 数据库日志损坏,后将该库从 alwayson 移出,先设置为简单模式 + 收缩日志,再设为完整模式 + 加入ag,再次执行 backup 成功了。此操作相当于丢弃了大量日志文件所占用的物理块。
Copyright © www.sqlfans.cn 2021 - 2026 All Right Reserved更新时间: 2026-07-22 20:05:44

results matching ""

    No results matching ""