如何恢复数据库
在本机操作,Debug的时候,一切似乎都在掌控之中。可是提交到服务器之后,一切显地都无比陌生。因为不熟悉SQL,准确来说就只会点Select,Update,Delete,Insert而已。昨天不小心误删了一张数据不多但是不在人工处理范围内的一张表内的数据。
因为知道SQL Server是有日志这种东西的,事后我表现地无比淡定,在事发一个小时以内。一个小时之后,我发现我无法掌控这一事件了。
上网查找了恢复数据的办法。有必要啰嗦一下。
问题1:
无论是远程端还是服务器端,都无法对数据库(假设数据库叫Test)进行除‘增删查改’的其它操作,譬如分离,脱机,还原...错误提示是
e.g.1 “无法分离 Test 数据库 因为它当前正在使用。”
e.g.2 “因为数据库正在使用,未获得对数据的排他访问权,操作异常终止”
反正嘛,就是说你丫不能阻止别人的访问。可我们就是要这样做的...只好跟它说拜拜了。
说拜拜的方法就是关掉所有访问数据库Test的进程。
createproc killspid (@dbnamevarchar(20))
as
begin
declare@sqlnvarchar(500)
declare@spidint
set@sql='declare getspid cursor for select spid from sysprocesses where dbid=db_id('''+@dbname+''')'
exec(@sql)
open getspid
fetchnextfrom getspid into@spid
while@@fetch_status<>-1
begin
exec('kill '+@spid)
fetchnextfrom getspid into@spid
end
close getspid
deallocate getspid
end
--用法
use master
exec killspid '数据库名'
PS:
代码我是这样理解的,定义一段杀死访问数据库进程的存储过程。写一段获取进程ID的代码,循环杀死每一个进程。最后调用存储过程。
虽然不了解存储过程,但是意思就是这样的吧。
问题2:
没有备份数据库,那该如何恢复数据呢
有个软件叫做Log Explorer 这个东西可以根据数据库的日志回到过去的任何一个时刻。
Log Explorer for SQL Server
打开log explorer file=>attach log file->选择服务器和登陆方式->connect->
选择数据库->attach->左面对话框中browse->view log->就可以看到log记录了
点击“View DDL Commands”里面就有很多drop table 命令
点击下面的“undo”按钮是生成表结构的语句(create table ....)
点击下面的“Salvage”按钮是生成插入语句的(insert into ...values....)
想恢复的话: 右键log记录 undo transation->选择保存文件名和路径->然后打开该文件到查询分析器里执行
T-sql代码就可以了
例如 如果log是delete table where ...的话,生成的文件代码就是insert table ....
log explorer使用的几个问题
对数据库做了完全 差异 和日志备份
备份时选用了删除事务日志中不活动的条目
再用Log explorer打试图看日志时
提示No log recorders found that match the filter,would you like to view unfiltered data
选择yes,就看不到刚才的记录了
如果不选用了删除事务日志中不活动的条目
再用Log explorer打试图看日志时,就能看到原来的日志
Log Explorer for SQL Server 是个好东西,但是这根本无法解决我的问题。数据库在服务器端,学校根本不会让我安装一个软件在服务器上面。而且我证实过,这个软件必须要在服务器端装服务器端软件的。所以,这个对于我来说,是泡汤的。但是不代表这不是一个利器。
最后我用了一个很蛋疼的方法解决了。
1.分离数据库,备份一个Test;
2.将数据库附加回去,用自带的恢复方式恢复到一个很久以前的状态;
3.将需要的那张表复制到备份的那个数据库;
4.将备份的那个数据库挂回去,原数据库删了。
这是一个很蛋疼而且碰巧那张表没被改的方法。
头一次知道DBA的重要性。
我的方法是一个很偶然的东西,希望大家分享一下真正能解决恢复问题的办法。当然,每隔一段时间备份是绝对没有错的。
方法
另外发现一个比较有技术性的可行的方法
1,如果误操作之前存在一个全库备份(或已有多个差异备份或增量备份),首先要做的事就是进进行一次日志备份
(如果为了不让日志文件变大而置trunc. log on chkpt.选项为1那你就死翘了)
backup log dbName to disk='fileName'
----注意:是日志备份!
2,恢复一个全库备份,注意需要使用with norecovery,如果还有其他差异或增量备份,则逐个恢复
restore database dbName from disk='fileName' with norecovery
3,恢复最后一个日志备份即刚做的日志备份,指定恢复时间点到误操作之前的时刻
restore log dbName from disk='fileName'
with stopat='date_time'
完整代码
----1,如果误操作之前存在一个全库备份(或已有多个差异备份或增量备份),首先要做的事就是进进行一次日志备份(如果为了不让日志文件变大而置trunc. log on chkpt.选项为1那你就死翘了)
backup log dbName to disk='fileName'
----注意:是日志备份!
----2,恢复一个全库备份,注意需要使用with norecovery,如果还有其他差异或增量备份,则逐个恢复
restore database dbName from disk='fileName' with norecovery
----3,恢复最后一个日志备份即刚做的日志备份,指定恢复时间点到误操作之前的时刻
restore log dbName from disk='fileName'
with stopat='date_time'
经过验证,这才叫有技术性!我那纯属“邓艾的屯‘田’”小孩子过家家。。。
参考的资料:
http://blog.163.com/liushui19860112@126/blog/static/132373046201052841232492/
作者:Ron Ngai
出处:http://rondsny.github.io
关于作者:断码码农一枚。
欢迎转载,但未经作者同意须在文章页面明显位置给出原文连接
如有问题,可以通过rondsny#gmail.com 联系我,非常感谢。
posted on 2012-02-28 22:00 Ron Ngai 阅读(4558) 评论(12) 编辑 收藏 举报