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