You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

QueryStore内部表数据库损坏:SQL页分配单元不匹配警报求助

DATE/TIME: 2/28/2018 9:26:42 AM
DESCRIPTION: 尝试在数据库9中获取逻辑页(1:3948712)失败。该页属于分配单元72057594045857792,而非72059184917512192。
COMMENT: (无)
JOB RUN: SQL Sentry 2.0 Alert Trap。在辅助副本的事件日志中发现3条相同消息:Source spid138 Message 尝试在数据库9中获取逻辑页(1:3948712)失败。该页属于分配单元...

我处理过不少这类Query Store页面分配异常的问题,结合你的警报信息,给你整理一套排查和解决的步骤:

排查步骤

先把问题的上下文摸清楚,再逐步定位根源:

  • 确认目标数据库:先搞清楚数据库ID 9对应的是哪个库,执行下面的查询:
    SELECT name FROM sys.databases WHERE database_id = 9;
    
    确认这个库是否启用了Query Store(大概率是,因为错误和Query Store内部表相关)。
  • 检查Query Store状态:查看Query Store是否处于只读或者异常状态,这可能是引发页分配问题的诱因:
    SELECT actual_state_desc, readonly_reason FROM sys.database_query_store_options;
    
    如果readonly_reason不为0,对应官方文档的取值排查原因(比如磁盘空间不足、内存压力等)。
  • 验证页面分配细节:用DBCC PAGE查看出错页面的具体信息,确认分配单元的归属:
    DBCC TRACEON(2588); -- 开启跟踪标记以支持DBCC PAGE输出
    DBCC PAGE(9, 1, 3948712, 3);
    
    对比返回的AllocationUnitId和警报中的两个ID,确认是否真的存在不匹配。
  • 执行数据库完整性检查:跑DBCC CHECKDB确认是否存在更广泛的数据库损坏:
    DBCC CHECKDB('你的数据库名') WITH NO_INFOMSGS, ALL_ERRORMSGS;
    
    重点关注和分配单元、Query Store内部表(sys.query_store_*系列表)相关的错误信息。
  • 排查系统日志和事件:查看SQL Server错误日志、Windows系统事件日志,有没有IO错误、磁盘故障、内存不足或者近期的备份/还原操作异常,这些都可能是损坏的根源。
解决方法

根据排查结果,对应不同的修复方案:

  • 重置Query Store(优先尝试):如果损坏仅局限于Query Store内部数据,重置是最安全的方法:
    1. 先禁用Query Store:
      ALTER DATABASE '你的数据库名' SET QUERY_STORE = OFF;
      
    2. 清理现有Query Store数据:
      ALTER DATABASE '你的数据库名' SET QUERY_STORE CLEAR;
      
    3. 重新启用并设置为读写模式:
      ALTER DATABASE '你的数据库名' SET QUERY_STORE = ON (OPERATION_MODE = READ_WRITE);
      
    操作完成后,监控警报是否消失。
  • 修复数据库完整性错误:如果DBCC CHECKDB发现了可修复的错误:
    • 对于轻度错误(比如索引损坏),使用REPAIR_REBUILD修复,不会丢失数据:
      DBCC CHECKDB('你的数据库名', REPAIR_REBUILD);
      
    • 如果是严重的分配单元错误,可能需要使用REPAIR_ALLOW_DATA_LOSS,但这个操作会丢失部分数据,一定要先做全量备份,并且在维护窗口执行:
      DBCC CHECKDB('你的数据库名', REPAIR_ALLOW_DATA_LOSS);
      
  • 修复辅助副本:因为辅助副本也出现了相同错误,说明损坏已经同步过去。修复主副本后,需要重新同步辅助副本:
    • 可以先移除辅助副本,然后重新添加并初始化;
    • 或者在主副本做一次全量备份+日志备份,还原到辅助副本并设置为同步状态。
  • 后续预防措施
    • 定期检查Query Store的状态和存储大小,设置合理的清理策略,避免数据堆积:
      ALTER DATABASE '你的数据库名' SET QUERY_STORE (CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30));
      
    • 及时安装SQL Server最新的累积更新(CU),很多Query Store的已知bug在后续补丁中已经修复;
    • 监控磁盘IO和空间,避免因为磁盘问题导致页损坏。

内容的提问来源于stack exchange,提问作者Peter

火山引擎 最新活动