आप लॉग बैकअप फ़ाइलों को क्वेरी करने के लिए इस प्रक्रिया को आज़मा सकते हैं और पा सकते हैं जिसमें लॉग बैकअप फ़ाइल (s) तालिका के स्तंभ का एक विशिष्ट मूल्य अभी भी / अंतिम मौजूद था।
उपयोगकर्ता को खोजने के लिए, यह जानने के बाद कि लॉग बैकअप का अंतिम मान क्या है, आप उस लॉग बैकअप तक एक डेटाबेस को पुनर्स्थापित कर सकते हैं और फिर मार्क स्टोरी-स्मिथ के उत्तर का पालन कर सकते हैं ।
कुछ पूर्वापेक्षाएँ
- जानिए किन मूल्यों से हटाए गए कॉलम
- पूर्ण पुनर्प्राप्ति मॉडल के अंतर्गत हैं और लॉग बैकअप ले रहे हैं
- आपके पास अपने लॉग बैकअप में दिनांक या पहचानकर्ता होते हैं, जैसे कि ओला हैलेनग्रेन के समाधान का उपयोग करते समय
अस्वीकरण
यह समाधान जलरोधी से बहुत दूर है, और बहुत अधिक काम करने की आवश्यकता है।
यह बड़े पैमाने पर वातावरण, या यहां तक कि कुछ छोटे परीक्षणों के अलावा किसी भी वातावरण पर परीक्षण नहीं किया गया है। वर्तमान रन SQL Server 2017 पर था।
आप मुहम्मद इमरान से नीचे की प्रक्रिया का उपयोग कर सकते हैं जो मैंने लाइव डेटाबेस के लॉग की सामग्री के बजाय लॉग बैकअप की सामग्री के साथ काम करने के लिए संशोधित किया था ।
इस तरह आप तकनीकी रूप से पुनर्स्थापना नहीं कर रहे हैं, बल्कि लॉग सामग्री को अस्थायी तालिका में डंप कर रहे हैं। यह शायद अभी भी धीमा होगा, और बग और मुद्दों के लिए बहुत खुला है। लेकिन यह काम कर सकता है, सिद्धांत ™ में।
संग्रहित प्रक्रिया fn_dump_dblog
लॉग फ़ाइलों को पढ़ने के लिए अनिर्धारित फ़ंक्शन का उपयोग करती है ।
परीक्षण वातावरण
इस डेटाबेस पर विचार करें, जहां हम कुछ पंक्तियों को सम्मिलित करते हैं, 2 लॉग बैकअप लेते हैं, और तीसरे लॉग बैकअप पर हम सभी पंक्तियों को हटाते हैं।
CREATE DATABASE WrongDeletesDatabase
GO
USE WrongDeletesDatabase
GO
BACKUP DATABASE WrongDeletesDatabase TO DISK ='c:\temp\Full.bak'
ALTER DATABASE WrongDeletesDatabase SET RECOVERY FULL
GO
CREATE TABLE dbo.WrongDeletes(ID INT, val varchar(255))
INSERT INTO dbo.WrongDeletes(ID,val)
VALUES (1,'value1')
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log1.trn'
GO
INSERT INTO dbo.WrongDeletes(ID,val)
VALUES (2,'value2')
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log2.trn'
GO
DELETE FROM dbo.WrongDeletes
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log3.trn'
GO
INSERT INTO dbo.WrongDeletes(ID,val)
VALUES (3,'value3')
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log4.trn'
GO
प्रक्रिया
आप यहां संग्रहीत प्रक्रिया को ढूंढ और डाउनलोड कर सकते हैं ।
मैं इसे यहां नहीं जोड़ सका क्योंकि यह चरित्र की सीमा से बड़ा है, और इस उत्तर को इससे भी कम स्पष्ट कर देगा।
इसके अलावा, आपको प्रक्रिया को चलाने में सक्षम होना चाहिए।
प्रक्रिया चल रही है
इसका एक उदाहरण, जब मैं अपनी सभी लॉग फाइल ( 4
) को संग्रहीत कार्यविधि में जोड़ता हूं और मान 1 की तलाश में प्रक्रिया चलाता हूं
EXEC dbo.Recover_Deleted_Data_Proc @Database_Name= 'WrongDeletesDatabase',
@SchemaName_n_TableName= 'dbo.WrongDeletes',
@SearchString = 'value1',
@SearchColumn = 'val',
@LogBackupFolder ='C:\temp\Logs\'
यह मुझे मिलता है:
ID val LogFileName
1 value1 c:\temp\Logs\log3.trn
1 value1 c:\temp\Logs\log1.trn
जहां हम पा सकते हैं कि पिछली बार ऑपरेशन कब value1
हुआ था, तो डिलीट करें log3.trn
।
कुछ और परीक्षण डेटा, विभिन्न स्तंभों के साथ एक तालिका जोड़ना
CREATE TABLE dbo.WrongDeletes2(Wow varchar(255), Anotherval varchar(255),Val3 int)
INSERT INTO dbo.WrongDeletes(ID,val)
VALUES (1,'value1')
INSERT INTO dbo.WrongDeletes2(wOw,Anotherval,Val3)
VALUES ('b','value1',1)
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log1_1.trn'
GO
INSERT INTO dbo.WrongDeletes(ID,val)
VALUES (2,'value2')
INSERT INTO dbo.WrongDeletes2(wOw,Anotherval,Val3)
VALUES ('c','value2',2)
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log2_1.trn'
GO
DELETE FROM dbo.WrongDeletes
DELETE FROM dbo.WrongDeletes2
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log3_1.trn'
GO
INSERT INTO dbo.WrongDeletes(ID,val)
VALUES (3,'value3')
INSERT INTO dbo.WrongDeletes2(wOw,Anotherval,Val3)
VALUES ('d','value3',3)
GO
BACKUP LOG WrongDeletesDatabase TO DISK = 'c:\temp\Logs\log4_1.trn'
GO
लॉग फ़ाइल नाम बदलना और प्रक्रिया को फिर से निष्पादित करना
EXEC dbo.Recover_Deleted_Data_Proc @Database_Name= 'WrongDeletesDatabase',
@SchemaName_n_TableName= 'dbo.WrongDeletes',
@SearchString = 'value1',
@SearchColumn = 'val',
@LogBackupFolder ='C:\temp\Logs\'
परिणाम
ID val LogFileName
1 value1 c:\temp\Logs\log1_1.trn
1 value1 c:\temp\Logs\log3_1.trn
1 value1 c:\temp\Logs\log3_1.trn
2
के val3
कॉलम में पूर्णांक ( ) की खोज करते हुए एक नया रनdbo.WrongDeletes2
EXEC dbo.Recover_Deleted_Data_Proc @Database_Name= 'WrongDeletesDatabase',
@SchemaName_n_TableName= 'dbo.WrongDeletes2',
@SearchString = '2',
@SearchColumn = 'Val3',
@LogBackupFolder ='C:\temp\Logs\'
परिणाम
Anotherval Val3 Wow LogFileName
value2 2 c c:\temp\Logs\log2.trn
value2 2 c c:\temp\Logs\log3.trn
मार्क स्टोरी स्मिथ के जवाब को लागू करना
अब हम जानते हैं कि यह तीसरी लॉग फ़ाइल में हुआ, चलो उस बिंदु तक पुनर्स्थापित करें:
USE master
GO
ALTER DATABASE WrongDeletesDatabase SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE WrongDeletesDatabase SET ONLINE
GO
RESTORE DATABASE WrongDeletesDatabase FROM DISK = 'c:\temp\Logs\Full.bak' WITH NORECOVERY,REPLACE
RESTORE LOG WrongDeletesDatabase FROM DISK = 'c:\temp\Logs\log1.trn' WITH NORECOVERY
RESTORE LOG WrongDeletesDatabase FROM DISK = 'c:\temp\Logs\log2.trn' WITH NORECOVERY
RESTORE LOG WrongDeletesDatabase FROM DISK = 'c:\temp\Logs\log3.trn' WITH RECOVERY
GO
USE WrongDeletesDatabase
GO
उनके जवाब में अंतिम क्वेरी चल रही है
SELECT
u.[name] AS UserName
, l.[Begin Time] AS TransactionStartTime
FROM
fn_dblog(NULL, NULL) l
INNER JOIN
(
SELECT
[Transaction ID]
FROM
fn_dblog(NULL, NULL)
WHERE
AllocUnitName LIKE @TableName + '%'
AND
Operation = 'LOP_DELETE_ROWS'
) deletes
ON deletes.[Transaction ID] = l.[Transaction ID]
INNER JOIN
sysusers u
ON u.[sid] = l.[Transaction SID]
मेरे लिए परिणाम (sysadmin)
UserName TransactionStartTime
dbo 2019/08/09 17:14:10:450
dbo 2019/08/09 17:14:10:450