问题背景

运维操作失误,在没有正常关闭sqlserver的情况下,将服务器关闭了,重启后某些表损坏(应该是某些页损坏了,没有损坏的页还能访问到数据,但是访问损坏了的页就有问题),目前数据库只有4.20号的备份。

报错信息

查询脚本:select * from t_jxjs_pctq where c_bh_tqxx = '8ae480b26320550e016323d098050175';

报错信息:HY000-[SQL Server] 数据库 ID 11,页[1:60682]已标记为RestorePending,可能表名磁盘已损坏,要从此状态进行恢复,请执行还原操作。

报错可能的原因

RestorePending一般是在进行页恢复的过程中出现的,就是在进行了restore操作之后但还没有进行recovery操作之前页的状态。出现这样的问题可以肯定这个表是损坏了,但是在查询数据的时候如果不会查询到损坏页面的数据话是不会报错的,也就是说可以有条件的使用这个表。参考资料

5.7号和4.20号的数据量对比

表名 4.20号 5.6号
T_JXJS_PCTQ 1716 2175
T_YWGY_WSQD_WS 7358 8275
T_JXJS_HYJL 244 287

数据库修复

--修复改数据库 1.此时我们需要将数据库设置成单用户模式:
右键点击数据库 -> 属性 -> 选项 -> 状态 -> 限制访问 -> 选择Single-> 确定。注意修复完成后需要改回多用户模式。
--2.使用dbcc checkdb进行数据库修复
DBCC CHECKDB ('db_xfzx', REPAIR_FAST)
--修复过程中报错信息:
T_JXJS_HYJL的 DBCC 结果。
消息 8928,级别 16,状态 2,第 1 行
对象 ID 885578193,索引 ID 1,分区 ID 72057594060341248,分配单元 ID 72057594075873280 (类型为 In-row data): 无法处理页 (1:70890)。有关详细信息,请参阅其他错误消息。
      DBCC 语句的修复级别导致避开了此修复。
消息 8939,级别 16,状态 98,第 1 行
表错误: 对象 ID 885578193,索引 ID 1,分区 ID 72057594060341248,分配单元 ID 72057594075873280 (类型为 In-row data),页 (1:70890)。测试(IS_OFF (BUF_IOERR, pBUF->bstat))失败。值为 12584969 和 -6。
      修复此错误要求首先修正其他错误。
消息 8976,级别 16,状态 1,第 1 行
表错误: 对象 ID 885578193,索引 ID 1,分区 ID 72057594060341248,分配单元 ID 72057594075873280 (类型为 In-row data)。在扫描过程中未发现页 (1:70890),但该页的父级 (1:704) 和上一页 (1:450709) 都引用了它。请检查以前的错误消息。
      修复此错误要求首先修正其他错误。
对象 'T_JXJS_HYJL' 的 6 页中有 249 行。
CHECKDB 在表 'T_JXJS_HYJL' (对象 ID 885578193)中发现 0 个分配错误和 3 个一致性错误。

--3.重建索引并修复,报一样的错
DBCC CHECKDB ('db_xfzx', REPAIR_REBUILD)

--4.在修复过程中发现T_YWGY_WSQD_WS,T_JXJS_HYJL均有此报错。同时检查其他库没有发现有损坏情况。

--5.尝试进行单个表修复,以及对损坏页的单独修复,均会报上面的的错。
dbcc checktable('t_jxjs_pctq',REPAIR_REBUILD)
dbcc page(11,1,60682,3)

dbcc checkdb并未能解决问题。

重建索引

1.执行了dbcc checkdb后,报错的信息里有索引 ID 1;这个信息的提供,可能是索引页的损坏。但是前面执行的DBCC CHECKDB ('db_xfzx', REPAIR_REBUILD)重建索引修复,并没能解决问题。

2.猜测:因为一个表中有多个索引,所以是不是单独重新生成每一个索引就能发现是哪个索引有问题呢?

3.在sqlserver客户端工具上面,对表T_JXJS_HYJL包括主键在内的三个索引进行重新生成,过程中有一个普通索引(I_JXJS_PCTQ_TQXX)的重新生成失败了,报错信息和最开始查询的信息一样。尝试重新组织该索引还是一样的问题。那么问题就出在I_JXJS_PCTQ_TQXX这个普通索引上了。

4.既然重建索引失败了,尝试删除该索引,发现可以删除,再重新创建该索引。

5.重建完成后再修复,DBCC CHECKDB ('db_xfzx', REPAIR_FAST) 。这时异常信息里面没有T_JXJS_HYJL表的异常信息。查看表中的数据已经正常,异常的数据可以正常查询,数据量的统计也已经正常。

6.同样T_YWGY_WSQD_WS该表有一个普通索引重新生成有问题,采用上面的方法也能解决。而T_JXJS_HYJL这张表的数据出现重建异常的是主键,由于有主键约束,所以不能删除索引,尝试修改为非主键,但是报错和查询一样的的错误。看来主键的数据不能这么做。最终由于该表只有两百多条数据,而且并不重要,直接恢复了4.20号的数据。

7.当然对表T_YWGY_WSQD_WS也可以采用将该表的数据通过select * into tableA from tableB;的形式插入到另外的表,重新创建该表后将数据恢复回来,然后重建索引。

结语

1.运行dbcc checkdb(db_name)检查数据库的完整性。根据日志判断可能由于某个索引的索引页缺失,索引不完整,导致某些数据查询的异常。而重新生成索引,不能成功,可以先删除该索引,再重新创建。

2.如果是主键索引则可以采用数据迁移的方式。

3.需要注意的是修复过程中不要使用DBCC CHECKDB ('数据名'', REPAIR_ALLOW_DATA_LOSS),REPAIR_ALLOW_DATA_LOSS该语句是可能丢失数据的。

4.修复完成后需要从单用户模式修改为多用户模式。

5.做到未雨绸缪,提前做好备份,每天备份,对备份的数据进行还原测试。做到有”备”无患

SqlServer索引页损坏恢复的更多相关文章

  1. 解剖SQLSERVER 第一篇 数据库恢复软件商的黑幕(有删减版)

    解剖SQLSERVER 第一篇  数据库恢复软件商的黑幕(有删减版) 这一系列,我们一起来解剖SQLSERVER 在系列的第一篇文章里本人可能会得罪某些人,但是作为一位SQLSERVER MVP,在我 ...

  2. 利用innodb_force_recovery修复MySQL数据页损坏

    现象:启动MySQL服务时报1067错误,服务无法启动. 查看xxx.err错误日志发现有数据页损坏信息: InnoDB: Database page corruption on disk or a  ...

  3. SqlServer索引的原理与应用

    索引的概念 索引的用途:我们对数据查询及处理速度已成为衡量应用系统成败的标准,而采用索引来加快数据处理速度通常是最普遍采用的优化方法. 索引是什么:数据库中的索引类似于一本书的目录,在一本书中使用目录 ...

  4. sqlserver索引小结

    1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书 ...

  5. 认识SQLServer索引以及单列索引和多列索引的不同

     一.索引的概念 索引的用途:我们对数据查询及处理速度已成为衡量应用系统成败的标准,而采用索引来加快数据处理速度通常是最普遍采用的优化方法. 索引是什么:数据库中的索引类似于一本书的目录,在一本书中使 ...

  6. 深入理解Sqlserver索引

    1. Sqlserver中索引分为聚集索引和非聚集索引: 聚集索引:表中数据的物理存储的顺序与索引顺序完全相同(字典的按拼音查法),检索效率比非聚集索引高,但对数据更新影响较大. 非聚集索引:表中数据 ...

  7. 数据结构~Sqlserver索引使用的B树

    B树相关概念 在B-树中查找给定关键字的方法是,首先把根结点取来,在根结点所包含的关键字K1,…,Kn查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功:否则,一定可以 ...

  8. sqlserver 索引的结构及其存储,索引内容

    sqlserver 索引的结构及其存储,sql server索引内容 文章转载,原文地址: http://www.cnblogs.com/panchunting/p/SQLServer_IndexSt ...

  9. [转]SqlServer索引的原理与应用

    索引的概念 索引的用途:我们对数据查询及处理速度已成为衡量应用系统成败的标准,而采用索引来加快数据处理速度通常是最普遍采用的优化方法. 索引是什么:数据库中的索引类似于一本书的目录,在一本书中使用目录 ...

随机推荐

  1. Python之unittest测试代码

    前言 编写函数或者类时,还可以为其编写测试.通过测试,可确定代码面对各种输入都能够按要求的那样工作. 本次我将介绍如何使用Python模块unittest中的工具来测试代码. 测试函数 首先我们先编写 ...

  2. 从字节码层面看“HelloWorld”

    一.HelloWorld 字节码生成 众所周知,Java 程序是在 JVM 上运行的,不过 JVM 运行的其实不是 Java 语言本身,而是 Java 程序编译成的字节码文件.可能一开始 JVM 是为 ...

  3. Android中AdapterView/Adapter的深度学习

    BaseAdapter的深度学习 博主工作了几年,也用了几年的ListView等AdapterView控件,但关于Adapter的一些问题并没有深入下去,终于有时间学习总结下关于BaseAdapter ...

  4. JavaWeb学习 (十八)————JSP标签

    一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...

  5. FFmpeg编解码处理4-音频编码

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584948.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...

  6. Python 的几种推导式

    推导式 comprehensions(又称解析式):是 Python 中很强大的.很受欢迎的特性,具有语言简洁,速度快等优点.推导式包括: 1. 列表推导式 2. 字典推导式 3. 集合推导式 对以上 ...

  7. T-SQL:CTE用法(十)

    CTE 也叫公用表表达式和派生表非常类似 先定义一个USACusts的CTE WITH USACusts AS ( SELECT custid, companyname FROM Sales.Cust ...

  8. [android] 手机卫士应用程序更新和签名

    弹出升级对话框 获取AlertDialog.Builder对象,通过new出来 调用Builder对象的setTitle()方法,参数:文本 调用Builder对象的setMessage()方法,参数 ...

  9. 如何完全卸载oracle和删除oracle在注册表中的注册信息

    卸载步骤介绍 1.停止所有Oracle相关的服务 操作方法: 控制面板-->管理工具 -->服务 -->将所有oracle开头的服务均停止 2.卸载Oracle 10g数据库服务器组 ...

  10. 【开发工具之Spring Tool Suite】6、用Spring Tool Suite简化你的开发

    如果你是一个喜欢用spring的人,你可能会在欣赏spring的强大功能外,对其各样的配置比较郁闷,尤其是相差较大的版本在配置文件方面会存在差异,当然你可以去花不少的时间去网上查找相关的资料,当你准备 ...