How To Recover Deleted Rows In SQL Server

In this article we will learn how to recover deleted data if it happens accidentally in SQL Server.

Note - All screenshots are applied to SQL Server 2012 Enterprise Evaluation Edition.
 

Introduction

 
We can recover deleted rows if we know the time when data is deleted We can achieve this goal using LSN ( Log Sequence Numbers ). As per Microsoft, “Every record in the SQL Server transaction log is uniquely identified by a log sequence number (LSN)". We will use these LSNs to recover our deleted data.
 

Recover Deleted Rows from SQL Server Table

 
To recover deleted rows from the table in database, database must be FULL Recovery or BULK-LOGGED Recovery Model.
 
SIMPLE Recovery doesn’t support transaction logs backup hence it is not possible in SIMPLE recovery model.
 
Steps Involved
 
Let’s set up environment for recovering deleted rows step by step:
 
Step 1
 
Create a database name RecoverDeletedData and set recovery model as FULL if it is not set as FULL.
 
Use the following command to create database,
  1. USE Master    
  2. GO    
  3. CREATE DATABASE [RecoverDeletedData]    
  4. ON PRIMARY    
  5. NAME = N'RecoverDeletedData',     
  6. FILENAME = N'D:\RecoverDeletedData\RecoverDeletedData.mdf'     
  7. SIZE = 4096KB, FILEGROWTH = 1024KB )     
  8. LOG ON     
  9. NAME = N'RecoverDeletedData_log',     
  10. FILENAME = N'D:\RecoverDeletedData\RecoverDeletedData.ldf',     
  11. SIZE = 1024KB, FILEGROWTH = 10%)     
  12. GO 
 
Figure 1 - Creating database RecoverDeletedData
 
Step 2
 
In Step 2 we will create a table for our environment.
  1. CREATE TABLE [Friends] (    
  2. [Sr.NoINT IDENTITY,    
  3. [Namevarchar (50),    
  4. [City] varchar (50));    
Step 3
 
After creating table “Friends”, let’s insert some values into it.
  1. USE RecoverDeletedData     
  2. GO     
  3.     
  4. insert into friends values (1, 'IanRox''Delhi')     
  5. insert into friends values (2, 'Jim''New York')    
  6. insert into friends values (3, 'Catherine''Las Vegas')     
  7. insert into friends values (4, 'John''California')     
  8. insert into friends values (5, 'Katie''Mexico')    
  9. insert into friends values (6, 'Sabrina''Indiana')     
  10. insert into friends values (7, 'Alfred''Hamburg')     
  11. insert into friends values (8, 'Vaibhav''Bangalore')     
  12. insert into friends values (9, 'Vijeta''Mumbai')     
  13. insert into friends values (10, 'YashRox''Sultanpur')  
Step 4
 
After inserting records check the inserted records with below query-
  1. USE RecoverDeletedData  
  2. GO     
  3. Select * from friends
 
Figure 2 - Fetching data from friends table of RecoverDeletedData database
 
Step 5
 
In Step 5, we will take full backup of database “RecoverDeletedData”
  1. USE RecoverDeletedData     
  2. GO     
  3. BACKUP DATABASE [RecoverDeletedData]     
  4. TO DISK = N'D:\RecoverDeletedData\RDDFull.bak'     
  5. WITH NOFORMAT, NOINIT, NAME = N'RecoverDeletedData-Full Database Backup',     
  6. SKIP, NOREWIND, NOUNLOAD, STATS = 10     
  7. GO
 
Figure 3 - Full Backup database RecoverDeletedData
 
Step 6
 
Now we will go ahead and delete some rows so that we can recover them with the help of LSNs.
  1. USE RecoverDeletedData     
  2. GO     
  3. DELETE friends     
  4. [WHERE [Sr.No] >5    
  5. GO
 
Figure 4 - Deleting rows from friends table
 
Step 7
 
Now check the “friends” again from below query:
  1. select * from friends
 
Figure 5 - Fetching rows from friends table after deletion
 
Ah! Only 5 records left as we deleted the records from 6th rows to 10th rows.
 
Step 8
 
Now take transaction log backup of the database.
 
USE RecoverDeletedData 
  1. GO     
  2. BACKUP LOG [RecoverDeletedData]     
  3. TO DISK = N'D:\RecoverDeletedData\RDDTrLog.trn'     
  4. WITH NOFORMAT, NOINIT,     
  5. NAME = N'RecoverDeletedData-Transaction Log Backup',     
  6. SKIP, NOREWIND, NOUNLOAD, STATS = 10     
  7. GO
 
Figure 6 - Backup transaction log for RecoverDeletedData
 
Step 9
 
Now to recover deleted rows we must gather information for deleted rows. To gather information about deleted rows we can run below query-
  1. USE RecoverDeletedData     
  2. GO     
  3. Select [Current LSN] LSN], [Transaction ID], Operation, Context, AllocUnitName     
  4. FROM     
  5. fn_dblog(NULLNULL)    
  6. WHERE Operation = 'LOP_DELETE_ROWS'
 
Figure 7 - Finding Transaction ID of deleted rows
 
From the above query we will get Transaction ID of deleted rows, now we have to find at what time rows got deleted.
 
Step 10
 
In Step 10, we will find exact time when rows got deleted with below query using Transaction ID “000:000002f1”:
  1. USE RecoverDeletedData     
  2. GO     
  3.     
  4. SELECT    
  5. [Current LSN], Operation, [Transaction ID], [Begin Time], [Transaction Name], [Transaction SID]    
  6. FROM    
  7. fn_dblog(NULLNULL)    
  8. WHERE    
  9. [Transaction ID] = ‘000:000002f1'    
  10. AND    
  11. [Operation] = 'LOP_BEGIN_XACT'  
After executing the above query we will get the current LSN “00000025:000001d0:0001” [Apology, here I forgot to take screenshot]
 
Step 11
 
In Step 11, we will proceed with restore operation to recover deleted rows with below query:
  1. USE RecoverDeletedData     
  2. GO     
  3.     
  4. RESTORE DATABASE RecoverDeletedData_COPY FROM     
  5. DISK = 'D:\RecoverDeletedData\RDDFull.bak'     
  6. WITH     
  7. MOVE 'RecoverDeletedData' TO 'D:\RecoverDB\RecoverDeletedData.mdf',     
  8. MOVE 'RecoverDeletedData_log' TO 'D:\RecoverDB\RecoverDeletedData_log.ldf',     
  9. REPLACE, NORECOVERY;     
  10. GO
 
Figure 8 - Restoring with FULL backup
 
Step 12
 
In Step 12, we will apply transaction log to restore deleted rows using LSN “00000025:000001d0:0001”
  1. USE RecoverDeletedData     
  2. GO     
  3. RESTORE LOG RecoverDeletedData_COPY   
  4. FROM DISK = N'D:\RecoverDeletedData\RDOTrLog.trn'   
  5. WITH STOPBEFOREMARK = ‘lsn:0x00000025:000001d0:0001'
 
Figure 9 - Restoring transaction log using LSN
 
Here one thing we need to remember that the LSN values are in hexadecimal form and for restoring with LSN value we need it in decimal form. To convert it to decimal form just put 0x before LSN like below in stopbeforemark clause
 
STOPBEFOREMARK = ‘lsn:0x00000025:000001d0:0001'
 
Step 13
 
As in above screenshot restore operation successfully completed, so here we check that our deleted records are back in RecoverDeletedData_Copy Database:
  1. USE RecoverDeletedData_Copy    
  2. GO     
  3. Select * from friends
 
Figure 10 - Fetching records from RecoverDeletedData_Copy database
 
Wow!! We got all records back…
 
In this way we can recover deleted records for any database provided database is in FULL or BULK-LOGGED Recovery model.
 
Final Words 
 
So from the above explanation and steps it is very clear that how we can recover deleted rows if we deleted it accidentally. But before that we must have idea about LSNs, transaction logs etc.