问题背景

运维操作失误,在没有正常关闭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. git reset命令使用

    版本回退 当前有三个commit提交版本commit1commit2commit3Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本上一个版本是HEAD^,上上一个版本是HEAD^^ ...

  2. 通过反编译深入理解Java String及intern

    一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会 ...

  3. 【Flask-RESTPlus系列】Flask-RESTPlus系列译文开篇

    0x00 背景介绍 因为工作上的需要,最近开始研究Python中实现Restful API的框架和工具包.之前粗略学习过Flask,由于它比较轻量级,感觉用它来实现Restful API再适合不过了. ...

  4. BBWebImage 设计思路

    BBWebImage 设计思路 BBWebImage 是高性能 Swift 图片组件,用于图片下载.缓存.编解码.编辑与展示. GitHub 地址: https://github.com/Silenc ...

  5. ThreadLocalMap里Entry为何声明为WeakReference?

    Java里,每个线程都有自己的ThreadLocalMap,里边存着自己私有的对象.Map的Entry里,key为ThreadLocal对象,value即为私有对象T.在spring MVC中,常用T ...

  6. Struts2学习(六)———— 文件上传和下载

    一.单文件上传 在没学struts2之前,我们要写文件上传,非常麻烦,需要手动一步步去获取表单中的各种属性,然后在进行相应的处理,而在struts2中就不需要了,因为有一个fileUpload拦截器帮 ...

  7. MySQL之库、表操作

    一.库操作 创建库 create database 库名(charset utf8 对库的编码进行设置,不写就用默认值) 库名可以由字母.数字.下划线.特殊字符,要区分大小写,唯一性,不能使用关键字, ...

  8. Oracle字符串函数

    Oracle字符串函数 平常我们用Oracle主要有两种字符串类型1.char始终为固定的长度,如果设置了长度小于char列的值,则Oracle会自动用空格填充的.当比较char时,Oracle用空格 ...

  9. 菜鸟入门【ASP.NET Core】13:Individual authentication 模板、EF Core Migration

    Individual authentication 模板 我们首先用VSCode新建一个mvc的网站,这个网站创立的时候回自动为我们创建Identuty Core以及EF Core的代码示例,我们可以 ...

  10. failed to install tomcat6 service ,check your setting and permissions

    出现的问题: 刚刚重新装了tomcat7,出现提示:Tomcat安装不成功.提示是:failed to install tomcat6 service ,check your setting and ...