在刀尖上跳舞,一次sql server 数据库恢复的过程

[ 2006-06-30 12:22:33 | 作者: progame ]
文字大小: | |
昨天晚上,在升级程序时,有一条SQL语句执行出错,报错为:
连接中断

当时晕了半天,怎么会连接中断,我在查询分析器里执行的啊,后来用
dbcc checkdb检查

出现一大堆的一致性错误
在用dbcc checkdb检查时,错误信息如下:
服务器: 讯息 8966,层级 16,状态 1,行 1
无法使用闩类型 SH 来读取和闩住分页 (1:3460)。sysindexes 失败。
英文的大致为:
Msg 8966, Level 16, State 5, Server 01AW01, Procedure , Line 3
[Microsoft][ODBC SQL Server Driver][SQL Server]Could not read and latch page
(1:177936) with latch type SH. PFS failed.

(因为我那个毁坏的数据库都无法再attach了,所以上面的错误是我再通过google查出来的)

以下忽略了我的尝试,痛苦,彷徨,为具体的修复过程,因为我这个是一个订阅数据库,所以如果所有方法都不行的话,我只能重建数据库再从DataCenter(Publisher)中把数据导过来,因为这个是单向的合并更新,所以如果导过来,是需要非常多的where语句的

直接truncate table那个无法操作的表,因为这个表数据不重要

尝试:
sp_dboption 'xxxxx','single user','true'
dbcc check db REPAIR_REBUILD

无效

取消订阅,将数据库中的配置修改为维护状态,防止应用程序继续对数据库操作,这个是我自己的配置,和数据库无关

取消订阅后,导致服务器clean subscriber时访问了不一致的数据,数据库变成suspect状态,并且连表都无法查看了

想赶紧停止服务,先备份数据库文件

失败,mdf文件无法支持copy了,CRC校验失败

后悔+伤心.....

google 查找置状态的SQL
UPDATE sysdatabases SET status = status ^ 32768 WHERE name = ...

状态变成置疑/紧急/只读模式

执行语句,看哪个表不可读
declare @tbl nvarchar(100),@clm nvarchar(100)
declare cur_tbl cursor for select name from sysobjects where xtype = 'U'
and name not like 'MSmerge%' and name not like 'sys%' and name not like 'ms%'
order by name
declare @sql nvarchar(4000)

open cur_tbl

FETCH NEXT FROM cur_tbl
INTO @tbl

WHILE @@FETCH_STATUS = 0
BEGIN

set @sql = 'select * from ' + @tbl + ' where 1=1'
 
print @sql
exec sp_executesql @sql
FETCH NEXT FROM cur_tbl
INTO @tbl

end

close cur_tbl
deallocate cur_tbl

能够执行,但不能完成,到某个表时会出现错误:
服务器: 消息 644,级别 21,状态 6,行 21
未能在索引页 (1:14528) 中找到 RID '168965c37e100' 的索引条目(索引 ID 0,数据库 '....')。

连接中断

灵机一动,反过来一下,把order by name改成desc

OK 发现有两个表不能读取

然后赶紧将所有数据写入到临时数据库,把
set @sql = 'select * from ' + @tbl + ' where 1=1'
改成
set @sql = 'select * into xxxx.dbo.' + @tbl + ' from ' + @tbl + ' where 1=1'

正向反向都来一次,这下稍稍安心了点,毕竟数据还在

备份这个临时数据库TEMP

恢复一个干净的数据库NEW

用sqldelta同步NEW的数据库结构到TEMP

无法完全同步,因为rowguid属性sqldelta无法同步

不去管它,用sqldelta同步数据(之前同步数据库结构就是为了同步数据,因为sqldetal需要主键做为比对的基础)

仍有部分无法同步成功(sqldelta总是不能尽善尽美)

用我的代码生成工具,生成脚本,自己同步部分表 insert into ... select ... from ...

重建订阅

置数据库中标志为非修改状态

到此结束
评论Feed 评论Feed: /feed.asp?q=comment&id=52

浏览模式: 显示全部 | 评论: 2 | 引用: 0 | 排序 | 浏览: 2660
引用 user*
[ 2007-06-25 21:41:26 ]
我也遇到类似问题,你能把解决的步骤说得更详细些吗?
引用 progame
[ 2007-06-25 22:44:49 ]
已经很清楚了

发表
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
用户名:   密码:   (非注册用户不需要输入密码) 注册?
验证码(不区分大小写) * 请输入验证码