คุณสามารถลองโพรซีเดอร์นี้เพื่อเคียวรีไฟล์บันทึกการสำรองข้อมูลและค้นหาไฟล์บันทึกการสำรองที่มีค่าเฉพาะของคอลัมน์ของตารางที่ยังคงอยู่ / ล่าสุด
ในการค้นหาผู้ใช้หลังจากที่คุณพบว่ามีการสำรองข้อมูลบันทึกค่าที่มีอยู่ล่าสุดคุณสามารถคืนค่าฐานข้อมูลจนกว่าจะมีการสำรองข้อมูลบันทึกนั้นแล้วทำตามคำตอบของMark Storey-Smith
ข้อกำหนดเบื้องต้นบางอย่าง
- รู้ค่าที่ลบคอลัมน์ใด
- อยู่ภายใต้รูปแบบการกู้คืนแบบเต็มและกำลังทำการสำรองข้อมูลบันทึก
- คุณมีวันที่หรือตัวระบุในการสำรองข้อมูลบันทึกของคุณเช่นเมื่อใช้โซลูชันของ Ola Hallengren
คำปฏิเสธ
วิธีแก้ปัญหานี้อยู่ไกลจากกันน้ำและจำเป็นต้องทำงานมากกว่านี้
มันไม่ได้รับการทดสอบในสภาพแวดล้อมขนาดใหญ่หรือแม้กระทั่งสภาพแวดล้อมใด ๆ นอกเหนือจากการทดสอบเล็กน้อย การดำเนินการปัจจุบันอยู่บน SQL Server 2017
คุณสามารถใช้ขั้นตอนด้านล่างจากMuhammad Imranที่ฉันแก้ไขเพื่อทำงานกับเนื้อหาของการสำรองข้อมูลบันทึกแทนเนื้อหาของบันทึกของฐานข้อมูลสด
วิธีนี้คุณจะไม่ทำการกู้คืนทางเทคนิค แต่จะทิ้งเนื้อหาของบันทึกในตารางชั่วคราวแทน มันอาจจะยังช้าและเปิดรับข้อบกพร่องและปัญหาได้มาก แต่มันสามารถใช้งานได้ในทางทฤษฎี™
กระบวนงานที่เก็บไว้ใช้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
ใช้คำตอบของMark Storey-Smith
เรารู้แล้วว่ามันเกิดขึ้นในล็อกไฟล์ที่สามมาคืนค่ากันจนถึงจุดนั้น:
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]
ผลลัพธ์สำหรับฉัน (ดูแลระบบ)
UserName TransactionStartTime
dbo 2019/08/09 17:14:10:450
dbo 2019/08/09 17:14:10:450