选择显示字体大小

靠bcp恢复sql server 2000数据库

sql server 2000在很多企业、电子商务网站的信息化平台得到了普遍的应用。可在日常运行中,因种种原因会造成sql server 2000运行出现故障,轻则出现“置疑”,重则数据库系统崩溃。本文以图示的方式,阐述某个大学的一次数据库数据恢复过程。同时也详细阐述了bcp实用工具的详细用法,希望这个处理过程和处理方法能对大家有所启示。

本文恢复数据使用pc环境如下:

1)windows 2000 server(简体中文)+sp4

2)microsoft sql server 2000企业版(简体中文)+sp3a

故障现象

1)游泳馆收费系统连接不上sql server 2000数据库

2)启动sql server服务失败。

3)打开企业管理器,启动服务也是失败(看不到数据库树目录)。

要命的是当技术员发现问题,已经卸载sql server 2000后重新安装过了,想利用master数据库是不可能了。更要命的是,居然没有2005年的备份数据库,只有2004年6月的数据库备份文件。



恢复尝试

第一招:附加数据库

拷贝sql server 2000数据文件zytk.mdf到d:recovery下。在企业管理器中,右键数据库,选择所有任务→附加数据库。单击浏览("...")按钮选择要附加的数据库mdf文件d:recoveryzytk.mdf,发现日志文件是错误的(如图1)。

此时拷贝zytk.ldf到d:recovery目录下,再进行上述步骤,日志文件仍是错误(就是那个可恶的红叉叉)。单击确定按钮,提示日志文件错误(如图2和图3)。

发现提示的日志文件路径是d:microsoft sql servermssql data zytk_log.ldf。于是在d盘建立d:microsoft sql servermssqldata目录,并将zytk.mdf拷贝这个目录下。继续尝试上述附加数据库步骤,日志文件的路径已经变化,仍旧没能附加数据库成功(错误1813)(如图4与图1相比)。



第二招:用t-sql附加数据库

在查询分析器中执行sql脚本

use master

exec sp_attach_db "zytk", "d:microsoft sql servermssqldatazytk.mdf","d:microsoft sql servermssqldatazytk_log.ldf"

查询分析器提示:

服务器:消息5105,级别16,状态4,行1

设备激活错误。物理文件名 'd:microsoft sql servermssql datazytk_log.ldf' 可能有误。

将d:recovery目录下zytk.mdf改名zytk-old.mdf。在企业管理器中新建数据库zytk,选择数据库文件路径为d:recoveryzytk_data.mdf,日志文件路径为d:recoveryzytk_ log.ldf。在企业管理器中,右键停止,以便停止sql server服务。待sql server服务停止后将d:recoveryzytk.mdf改名zytk_data-new.mdf,同时将zytk-old.mdf改名为zytk_data.mdf,在企业管理器中启动sql server服务。数据库zytk将会置疑。

在查询分析器中执行sql脚本:

use master

select * from sysdatabases

where name='zytk'

看到数据库的status=1073741840,下面我们的目标是要将这个值修改到32768(紧急模式)再到16(假正常模式,这是我在这个故障处理中的叫法)。

缺省情况下,sql server不允许修改status值。直接作update,系统提示服务器: 消息 259,级别 16,状态 2,行 1未启用对系统目录的特殊更新。系统管理员必须重新配置 sql server 以允许这种操作。

所以先执行sql脚本,让sql server允许我们修改status值:

sp_configure 'allow updates', 1

reconfigure with override

修改status到32768(紧急模式),执行sql脚本:

update sysdatabases

set status=32768

where name='zytk'

在查询分析器中执行sql脚本,检查数据库完整性。

dbcc checkdb ('zytk') with all_errormsgs

执行结果有很多错误(具体执行结果见03checkdb-zytk结果.txt),跟笔者估计一致,数据库索引出了大问题。下面摘录其中一个错误:

对象 'cw_check_detail' 有 0 行,这些行位于 0 页中。

服务器: 消息 8936,级别 16,状态 1,行 1

表错误: 对象 id 181575685,索引 id 1。b 树链的链接不匹配。(1:4987)->next = (1:2601),但 (1:2601)->prev = (1:4947)。

在查询分析器中执行sql脚本,将数据库zytk的status修改为16:

update sysdatabases

set status=16

where name='zytk'

刷新数据库,zytk(紧急模式)转变为zytk。注意此时不能重新启动sql server服务!否则数据库zytk的状态还会变成置疑。这时,数据库处理算是成功一半!这个假正常模式(我的叫法)还是不能做数据库备份的。否则会提示如图5的错误。

不过这时可以看到那些可恨又可爱的表及表中的数据了。

在d:recovery下建立目录bcp,再在d:recoverybcp下建立error目录。利用sql server数据库的sysobjects表可以生成批量的bcp命令:

数据库中各表导出所有表的数据:

use  %1

select 'bcp  %1..' + name +

' out  d:recoverybcp' +name + '.txt -c -s%2  -u%3 -p%4 >d:recoverybcperror out_'+name+'.txt' from  sysobjects where type = 'u' order by name

从数据文件导回到数据库中的各表:

use  %1

select 'bcp  %1..' + name +

' in  d:recoverybcp' +name + '.txt -c -s%2  -u%3 -p%4 >d:recoverybcperrorin_'+name+'.txt' from sysobjects where type = 'u' order by name

  注意:type = "u",u必须大写,表用户自定义表。-s服务器,-p密码,%1为数据库,%2为本机sql server实例名,一般就是计算机名,%3为登录账户,一般为sa,%4为登录密码。

本文中具体的例子如下:

select 'bcp  zytk..' + name +

' out  d:recoverybcp' +name + '.txt -c -stech  -usa -p123456 >d: recoverybcperrorout_'+name+'.txt' from sysobjects where type = 'u' order by name

将上述sql脚本的查询结果全选后另存为批处理文件zytk.bat。用于从数据库zytk中各表导出以表名命名的txt文件:

select 'bcp  zytk015..' + name +

' in  d:recoverybcp' +name + '.txt -c -stech  -usa -p123456 >d: recoverybcperrorin _'+name+'.txt' from sysobjects where type = 'u' order by name

将上述sql脚本的查询结果全选后另存为批处理文件zytk015.bat。用于将上述各表的txt文件导回到数据库zytk015。执行zytk.bat,执行完毕后要检查d:recoverybcperror下的每个out_表名.txt文件(见error_outfiles.rar),查看是否有误。当然导入后要检查in表名.txt文件,查看是否有误。这是必须的,笔者因想偷懒,结果因导入数据不完整而重新恢复多花了半天,教训啊!我处理的数据库表一共有166个,为了提高恢复准确性,最好能找个人一起帮助看着过程是否有误。

新建zytk015要保证跟zytk一样的表结构(如主键、索引等,本文不再赘述,本文是从zytk中生成sql脚本,然后新建数据库(下转第71页)(上接第70页)zytk015后执行创建表、主键、索引脚本。当然一般还有视图存储过程加密过的,是不能导出为sql脚本,那得想其它的办法,本文是还原2004年的数据库来实现的)。

执行zytk015.bat,执行完毕后要检查d:recoverybcperror每个in_表名.txt文件(见error_infiles.rar)。笔者遇到一个历史流水表导入失败,后来经过分时间段导入,多次试验才得以成功。恢复的时候一定要细心,并且记录关键步骤的操作内容,否则做到哪一步,自己都晕菜了,更不用说成功地恢复数据库了!如果在zytk015数据库中能看到数据,那就是大功告成了。不过不要得意哦,还得运行游泳收费系统来测试数据的正确性。测试之前记得要备份数据库哦。

最后,有个问题要说明一下:如果表间有关联,使用bcp恢复起来就麻烦一点。一般的做法可以把外键之类的表间关系去掉,等导入数据后在用sql脚本重新创建这些关系。这个做法数据的有效性得由我们自己去判断了,如果有问题还得手工修改(一般需要开发人员协助,因为只有他们才能去查代码)。

(  


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons