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对应的是哪个库,执行下面的查询:
确认这个库是否启用了Query Store(大概率是,因为错误和Query Store内部表相关)。SELECT name FROM sys.databases WHERE database_id = 9; - 检查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确认是否存在更广泛的数据库损坏:
重点关注和分配单元、Query Store内部表(DBCC CHECKDB('你的数据库名') WITH NO_INFOMSGS, ALL_ERRORMSGS;sys.query_store_*系列表)相关的错误信息。 - 排查系统日志和事件:查看SQL Server错误日志、Windows系统事件日志,有没有IO错误、磁盘故障、内存不足或者近期的备份/还原操作异常,这些都可能是损坏的根源。
解决方法
根据排查结果,对应不同的修复方案:
- 重置Query Store(优先尝试):如果损坏仅局限于Query Store内部数据,重置是最安全的方法:
- 先禁用Query Store:
ALTER DATABASE '你的数据库名' SET QUERY_STORE = OFF; - 清理现有Query Store数据:
ALTER DATABASE '你的数据库名' SET QUERY_STORE CLEAR; - 重新启用并设置为读写模式:
ALTER DATABASE '你的数据库名' SET QUERY_STORE = ON (OPERATION_MODE = READ_WRITE);
- 先禁用Query Store:
- 修复数据库完整性错误:如果
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和空间,避免因为磁盘问题导致页损坏。
- 定期检查Query Store的状态和存储大小,设置合理的清理策略,避免数据堆积:
内容的提问来源于stack exchange,提问作者Peter




