SQL Server 误操作解决方案
原文出处:http://blog.csdn.net/dba_huangzj/article/details/8491327
问题:
经常看到有人误删数据,或者误操作,特别是 UPDATE和 DELETE 的时候没有加 WHERE,然后就扎心了。
人非圣贤孰能无过,做错可以理解,但不能纵容,这个以后再说,现在先来解决问题。
遇到这种情况,一般都是没有做备份,不然也不会来发问了。首先要 冷静!!!,否则会有更大的灾难。直到你放弃。话不多说,请看下文。
/*****************
步骤:
1、将数据库属性》选项》恢复模式,设置为完整。可使用下面语句查询当前恢复模式
SELECT recovery_model,recovery_model_desc
FROM sys.databases
WHERE name =’DataBaseRecover’
确保数据库的恢复模式位“完整”模式
2、做1次“完整”备份。使用以下语句可查询备份信息
SELECT database_name,recovery_model,name,backup_finish_date
FROM msdb.dbo.backupset
3、插入一些数据。
4、删除数据。
USE DataBaseRecover
GO
WAITFOR TIME '10:29'
DELETE FROM dbo.STUDENT
SELECT * FROM dbo.STUDENT
为了定位是啥时候发生的,加了一个waitfor命令,让它在某个时间发生,这样恢复的时候就有准确性。
5、再做1“完整”备份。
6、断开数据库所有连接
7、做一次 “日志尾部备份” !!!!!!
(1)使用可视化工具备份
右击数据库》任务》备份》
常规:【备份类型:事务日志】
选项:【可靠性:√ 完成后验证备份;√ 写入介质前检查校验】
【事务日志:√ 备份日志尾部】
点击确定。
(2)使用语句备份
USE Master
GO
BACKUP LOG [DataBaseRecover] TO DISK = N'F:\DataBaseRecover_TransLog_Backup.bak' WITH NO_TRUNCATE , NOFORMAT, NOINIT, NAME = N'DataBaseRecover-事务日志 备份', SKIP, NOREWIND, NOUNLOAD, NORECOVERY , COMPRESSION, STATS = 10, CHECKSUM
GO
declare @backupSetId as int
select @backupSetId = position from msdb..backupset where database_name=N'DataBaseRecover' and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=N'DataBaseRecover' )
if @backupSetId is null begin raiserror(N'验证失败。找不到数据库“AdventureWorks”的备份信息。', 16, 1) end
RESTORE VERIFYONLY FROM DISK = N'E:\DataBaseRecover_TransLog_Backup.bak' WITH FILE = @backupSetId, NOUNLOAD, NOREWIND
GO
如果备份不了,使用以下语句查看,并把spid杀掉
SELECT * FROM sys.sysprocesses WHERE dbid=DB_ID('DataBaseRecover')
然后kill掉。接着继续备份。
8、此时,数据库处于“正在还原“状态
9、开始还原
(1)还原文件和文件组(数据库):
常规》选择最近的一次“完整”备份
选项》恢复状态:选择“不对数据库执行任何操作”
(2)还原“事务日志”
常规》时间点:把时间点指定到你误删除的时间之前
(这里我的删除操作是10:29:00,我这里还原时选择的是10:28:00)
选项》恢复状态:选择“回滚未提交的事务”
10、完成。检查数据是否恢复
总结:
平时尽量做备份,别等到出问题来喊急,数据无价,操作需谨慎,那以后出问题就别怪微软了。
本文中的方法看上去有点繁琐,但是实操几次就觉得好了,但是步骤建议严格按照上面说的,因为一旦操作错误,就很麻烦,此时再次强调——冷静冷静再冷静!!!!!!
这种方法有几个缺点:
1、 如果你发现误操作以后还有很多人做了操作,那么你还原成功后,别人的操作就会冲掉,所以发生误操作后,要马上停止别人对数据库的操作。
2、 这个方法要对数据库独占,所以你想偷偷恢复是不行的了。勇敢承认错误吧。
对于核心数据表,还是要先做好预防操作,可以看:SQLServer恢复表级数据。
******************/
本文作者测试用例:
/***************************
准备:
创建测试数据库,数据表,插入默认数据
****************************/
/*******************创建数据库****************************/
IF db_id('DataBaseRecover') IS NOT NULL
PRINT db_id('DataBaseRecover')
DROP DATABASE DataBaseRecover
GO
CREATE DATABASE DataBaseRecover
GO
USE DataBaseRecover
GO
/********************创建学生表***************************/
CREATE TABLE STUDENT(
StuId INT IDENTITY(,) PRIMARY KEY NOT NULL,
StuName NVARCHAR() NOT NULL
)
EXEC sys.sp_addextendedproperty @name = N'MS_Description', -- sysname
@value = N'学号', -- sql_variant
@level0type = N'USER', -- varchar()
@level0name = N'DBO', -- sysname
@level1type = N'TABLE', -- varchar()
@level1name = N'STUDENT', -- sysname
@level2type = N'COLUMN', -- varchar()
@level2name = N'StuId' -- sysname
EXEC sys.sp_addextendedproperty @name = N'MS_Description', -- sysname
@value = N'学生姓名', -- sql_variant
@level0type = N'USER', -- varchar()
@level0name = N'DBO', -- sysname
@level1type = N'TABLE', -- varchar()
@level1name = N'STUDENT', -- sysname
@level2type = N'COLUMN', -- varchar()
@level2name = N'StuName' -- sysname
/********************插入默认数据****************************/
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户001' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户002' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户003' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户004' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户005' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户006' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户007' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户008' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户009' )
INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户010' )
/*********************创建得分表*******************************/
IF OBJECT_ID('SCORES','U') IS NOT NULL
DROP TABLE SCORES
GO
CREATE TABLE SCORES
(
SCOREID INT IDENTITY(, )
NOT NULL
PRIMARY KEY ,
STUID INT NOT NULL ,
SCORE DECIMAL NULL
);
GO
/********************插入默认数据****************************/
INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( , )
INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( , )
INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( , )
INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( , )
INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( , )
INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( , )
INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( , )
/**查询:学生表*/
SELECT STUID,StuName FROM dbo.STUDENT
/**查询:得分表*/
SELECT SCOREID,STUID,SCORE FROM dbo.SCORES