笔记18-徐 SQLSERVER常见错误解读

笔记18-徐 SQLSERVER常见错误解读

  1 --SQLSERVER常见错误解读
  2 
  3 --823错误
  4 --823错误是发出一个页面读写请求时发生的,和读写的内容没有关系
  5 ---,所以823错误和SQL本身没有关系。通常是物理数据文件损坏或者
  6 --硬件出现问题。
  7 
  8 --修复方法:DBCC CHECKDB很难修复
  9 
 10 
 11 --824错误 原因基本是I/O子系统的问题,可以负责任地说SQL自己绝少会导致824错误的
 12 --此错误表明Windows已经从磁盘成功读取页,但SQLSERVER检测到页中存在逻辑错误
 13 --常见逻辑错误:
 14 
 15 --1、checksum:
 16 --SQL在写入每个页面时,根据页面里的数据算出一个校验值,一同存储到页面里。当下次读取页面的时候,
 17 --在根据这次读到的页面数据,算出一个新的校验值。如果写入和读出的数据一模一样,那么两个校验值一
 18 --定是相等的。而如果两个校验值不相等,意味着上次SQL写入的数据和这次读出的一定不同,现在读出来
 19 --的数据有问题。通过校验值SQL能发现数据页面损坏,这个功能是SQL2005以后引入的
 20 
 21 --2、torn page
 22 --SQL2000引入的残缺页(torn page)保护,是一种对电源故障导致的页损坏进行检测的方法。
 23 --页的每个512B扇区末尾会放置一个2位签名(在这之前会把原来的2位复制到页头之后)每次
 24 --进行写操作时,这个签名在二进制01和10之间交替。这样始终可以确定是否只有部分扇区写到
 25 --磁盘。如果稍后读取页时发现某个位的状态不正确,则说明该页没有被正确写入。
 26 --如果页面没有被正确写入,因此检测到问题页面,称为残缺页。相对于checksum,残缺页使用
 27 --的资源最少,但是它的算法太简单,无法检测到磁盘硬件故障导致的所有错误
 28 --不知道01 还是10 是指明那个扇区被正确写入
 29 
 30 --3、short transfer
 31 --读到的数据长度比预期的少。例如,一个读取要求预期可以读到8KB的数据,可是实际只返回了
 32 --4KB。这意味着当前读到的页面有损坏
 33 
 34 --4、bad page id
 35 --在读到页面后,SQL会比较页面开头存储的页面编号和自己请求的目标编号。如果发现自己
 36 --想要读取的页面是第200页,而读到的内容里显示它是第100页,SQL就会触发824错误。
 37 --这种错误经常是因为I/O子系统没有正确处理SQL的请求,传给SQL一个错误的页面,甚至
 38 --是一个空页面
 39 
 40 --5、restore pending
 41 --在SQL2005以后的企业版里,用户可以要求在做还原的时候跳过一些有损坏的页面(continue after error)
 42 --延迟的错误。这些跳过的页面被标识成“restore pending”.如果用户想去访问它,也会遇到824错误
 43 
 44 
 45 --6、stale read
 46 --由于硬件系统发生漏写的现象,checksum和torn page算法都不能检测到错误。
 47 --可以打开SQL启动参数开关 /T818 以后,SQL会在内存维护一张哈希表,记录下自己所有做过的写入
 48 --的动作的页面的LSN值。在下次读出页面的时候去比较这两个值是否相等。由于LSN是自动增长的唯一值,
 49 --每个发生新修改的页面,LSN的值会比原来的要大。所以如果读到的LSN的内存中存放的不一样,就
 50 --说明上次写入的请求没有真正完成。触发824错误
 51 --net start MSSQLSERVER /t818
 52 
 53 --修复方法:DBCC CHECKDB能修复,但是只是逻辑修复,会有部分数据丢失
 54 
 55 
 56 
 57 --605错误
 58 --605也是一个非常有名的数据库损坏错误。此错误通常表示指定数据库中的页或分配已经损坏
 59 --SQL会在根据页链接或使用索引分配映射IAM读取属于表的页时,检测到此损坏。分配给表的
 60 --所有页必须属于与该表相关联的分配单元之一。如果页眉中包含的分配单元ID与表相关联的分配
 61 --单元ID不匹配,将引发此异常。。错误消息中列出的第一个分配单元ID是页眉中的ID,第二个分配
 62 --单元ID是表相关联的ID
 63 
 64 --严重级别21:可能存在数据损坏,造成原因包括损坏的页链、损坏的IAM或该对象的sys.objects目录视图
 65 --中存在无效条目(即是页面失去了链接)。这些错误通常由硬件或磁盘驱动程序引起
 66 
 67 --严重级别12:存在暂时性错误,即在缓存中出现错误,但不表示对磁盘上的数据造成破坏。
 68 --包括:
 69 --(1)操作系统过早地通知SQL已完成某个I/O操作,尽管不存在实际的数据损坏,但显示错误消息
 70 --(2)运行带有优化器提示NOLOCK查询,或将事务隔离级别设置为READ UNCOMMITTED,当使用NOLOCK
 71 --或READ UNCOMMITTED的查询尝试读取被其他用户移走或更改的数据时,将发生605错误。
 72 --若要验证是否是605错误,请稍候重新运行该查询
 73 
 74 --修复方法:如果数据访问发生该错误,运行DBCC CHECKDB没有显示错误,那么605错误是暂时的
 75 --605意味着页面分配出现问题,所以也是一个非常严重的数据库损坏。一般用DBCC CHECKDB也很难修复
 76 
 77 
 78 --以下这些错误都是使用DBCC CHECKDB来修复
 79 --有些不丢数据能修复,有些丢数据能修复,有些丢数据也不能修复
 80 
 81 --(1)PFS页面头有损坏
 82 --(2)系统表中的聚集索引页面有损坏
 83 --(3)某个字段的值不符合字段数据类型定义
 84 --(4)元数据有损坏
 85 
 86 
 87 -----------------------DBCC CHECKDB-------------------------------------------------------------------------
 88 --DBCC CHECKDB完成两项任务
 89 --(1)检查数据库里有没有损坏发生
 90 --(2)尽力修复数据库损坏,使数据能够被正常访问
 91 --所以即使是一个正常运行的数据库,也建议定期运行这句命令,以确保没有损坏发生。
 92 --对于已经发生访问错误的数据库,应该在第一时间运行这句命令,了解损坏范围和程度
 93 
 94 --检查指定数据库中所有对象的逻辑和物理完整性
 95 --1、首先检查一些关键的系统表
 96 --2、对数据库运行DBCC CHECKALLOC
 97 --3、对数据库中的每个表和视图运行DBCC CHECKTABLE
 98 --4、对数据库运行DBCC CHECKCATALOG
 99 --5、验证数据库中每个索引视图的内容
100 --6、验证数据库中的Service Broker数据
101 
102 --这意味着运行了DBCC CHECKDB,就不必再单独运行DBCC CHECKALLOC、DBCC CHECKTABLE、DBCC CHECKCATALOG
103 --也意味着单独运行DBCC CHECKALLOC、DBCC CHECKTABLE、DBCC CHECKCATALOG不能完成DBCC CHECKDB的所有功能
104 --但是至少完成了大部分功能
105 
106 --1、在检查数据库之前SQL需要去了解这个数据库到底存放了什么样的数据,也就是所谓数据库的“元数据”。没有这些
107 --信息,SQL无法知道自己将要去访问什么样的表格和怎样解释读到的记录
108 
109 --SQL2000关键系统表:
110 --sysindexes
111 --sysobjects
112 --syscolumnes
113 
114 --这些系统表存放的是表格和索引的定义信息,以及表格里每一个字段的数据类型定义
115 --所以SQL必须要确认这些表完好无损
116 
117 
118 --SQL2005关键系统表:
119 --sysallocunits
120 --syshobts            --hobt:堆或B树
121 --syshobtcolumnes
122 --sysrowsets
123 --sysrowsetcolumns
124 
125 --SQL2000有3个关键系统表 SQL2005有5个关键系统表
126 --SQL2005里的关键系统表只有在DAC模式才能看到(但是我测试的时候使用DAC都不能看到关键系统表)
127 --每一张系统表都有一个聚集索引
128 
129 
130 --2、DBCC CHECKALLOC
131 --检查数据库所有页的分配。验证各种内部结构,这些结构可用于跟踪这些页,以及它们之间的关系
132 
133 
134 --3、DBCC CHECKTABLE
135 --是否已正确连接索引、行内、LOB以及行溢出数据页
136 --索引是否按照正确的顺序排列
137 --各指针是否一致
138 --每页上的数据是否合理(包括计算列)
139 --页面偏移量是否合理
140 --基表的每一行是否在每个非聚集索引中具有匹配的行,以及非聚集索引的每一行是否在基表中具有匹配的行
141 --已分区的表或索引的每一行是否都位于正确的分区中
142 
143 
144 --4、DBCC CHECKCATALOG
145 --检查指定数据库系统表里记录的元数据逻辑一致性。
146 --在sys.columns视图里,有一个列不属于sys.objects里的任何一个表格或视图
147 --在外键视图sys.foreign_keys里的一个外键在sys.indexes里找不到对应的索引
148 --某个对象的父对象不存在。(例如有一个主键对象存在,但是主键所依附的表格不存在了)
149 --这些错误除非用户自己去直接修改系统表里的数据否则不应该出现!!!!!!!!!!!!!!!!!!!!!!!!!!
150 
151 --5、验证数据库中每个索引视图的内容
152 --SQL支持在某些视图上建立索引,以提高视图的性能。在视图中一些经过计算的字段值,SQL会将
153 --它们存储到索引页面里。下次可以直接使用,而不需要再做计算
154 --如果视图查询的源数据量非常大,可以跳过这一步,可以使用PHYSICAL_ONLY这个参数
155 
156 --6、验证数据库中Service Broker数据
157 --如果SQL使用了Service Broker的功能,SQL还会调用Service Broker的组件,检查相关的系统对象
158 --Service Broker的queue、pipeline等 是否正常。这部分和传统的表格索引没有直接关系
159 
160 --如果你的数据库没有说“ 0 allocation errors” 和“0 consistency errors”,而是有若个
161 --错误,就意味着数据库有损坏,赶紧修吧
162 
163 
164 
165 ------------------------DBCC CHECKDB提供的修复方法--------------------------------------------
166 --默认DBCC CHECKDB只会验证数据库是否完好,不会主动做修复数据库的动作
167 --repair_allow_data_loss     修复所有错误,执行修复可能会丢失数据
168 --repair_rebuild    快速修复以及耗时修复(重建索引、非聚集索引中的额外键),执行修复时不会丢失数据
169 --repair_fast  未执行任何修复,只是为了向后兼容性
170 
171 --解决方法:
172 --1、DBCC CHECKDB(GPOSDB)
173 --有错误的情况下
174 --2、单用户模式下
175 ALTER DATABASE GPOSDB SET SINGLE_USER
176 DBCC CHECKDB(GPOSDB,REPAIR_REBUILD)
177 
178 --还是不能修复
179 --3、单用户模式下 紧急模式下
180 --应当是最后手段,并只有在无法从备份还原数据库时才采用
181 --如果DBCC CHECKDB成功,修复操作不会考虑表本身或表之间可能存在的任何约束
182 --,如果指定的表与一个或多个约束有关,建议在修复操作后运行DBCC CHECKCONSTRAINTS
183 --建议运行DBCC CHECKDB(GPOSDB,REPAIR_ALLOW_DATA_LOSS)之前备份数据库,因为
184 --DBCC CHECKDB造成的修改,可能会无法接受,而这个时候也无办法再用备份恢复的方法
185 --恢复数据库了
186 --只有万不得已的时候才使用DBCC CHECKDB(GPOSDB,REPAIR_ALLOW_DATA_LOSS)
187 
188 ALTER DATABASE GPOSDB SET EMERGENCY    --紧急只读模式
189 ALTER DATABASE GPOSDB SET SINGLE_USER
190 DBCC CHECKDB(GPOSDB,REPAIR_ALLOW_DATA_LOSS)
191 USE GPOSDB
192 DBCC CHECKCONSTRAINTS(systempara)
193 
194 
195 --还还是不能修复
196 --1、恢复数据库备份
197 --2、如果是用户表、视图、存储过程损坏,可以DROP掉试试
198 --3、使用紧急只读模式,使用导入导出数据或者select into  导出数据ALTER DATABASE GPOSDB SET EMERGENCY
199 --各个表的状态将会不一致,一般在逻辑上会有很大问题
200 
201 
202 
203 --安装固件和各种软件的升级补丁
204 --SQLSERVER2000:SQLSERVER2000 SP4 +hotfix build 2245
205 --SQLSERVER2005:现在还没有发现导致数据库损坏的bug
206 --SQLSERVER2008:现在还没有发现导致数据库损坏的bug
207 --WindowsXP:升级到WindowsXP SP3
208 --Windows2000:升级到Windows2000 SP4 +hotfix KB838647 +hotfix 905205(scsiport.sys)
209 --Windows2003:升级到Windows2003 SP2 +hotfix KB940467(storport.sys)
210 --Windows2008:现在还没有发现会导致数据库损坏的bug

 

posted @ 2013-07-27 15:39 桦仔 阅读(...) 评论(...) 编辑 收藏