Search This Blog

Showing posts with label SQL Recovery Steps. Show all posts
Showing posts with label SQL Recovery Steps. Show all posts

SQL Recovery models

For each database that you create in SQL Server, with the exception of the system databases, you can configure it to use one of three possible recovery models (simple, full, bulk-logged).  Here is a simple script to display the recovery models of all on-line databases:
SELECT name, (SELECT DATABASEPROPERTYEX(name, 'RECOVERY')) RecoveryModel FROM master..sysdatabases ORDER BY name
If you are running SQL Server 2005 or later, you can use this script instead:
SELECT name, recovery_model_desc FROM master.sys.databases ORDER BY name
This is how you can change a database's recovery model to the simple recovery model:
ALTER DATABASE AdventureWorks SET RECOVERY SIMPLE
to the full recovery model:
ALTER DATABASE AdventureWorks SET RECOVERY FULL
and to the bulk-logged recovery model:
ALTER DATABASE AdventureWorks SET RECOVERY BULK_LOGGED
Which recovery model do you need to use?  It depends on how much data you can afford to lose.  Let's use the following diagram to illustrate the difference between the recovery models, where a full database backup is performed at 9:00 a.m, and 11 a.m.
rm01_a

The simple recovery model
Assume that there was a hardware failure at 10:45  a.m.  If the database was using the simple recovery model, you would have lost 105 minutes of work.  The latest point at which you can recover the database to is 9:00 a.m, since that was the time the last full backup that was made.  You could schedule differential backups to run periodically e.g.
rm02_a
In this case, you would lose 45 minutes of work.  Now, assuming that a user deleted a critical table at 9:50 a.m.  Can you recover to the point in time just before the deletion?  No.  The differential backup contains only the changed data pages.  It cannot be used to restore to a specific point in time.  You'll have to restore the database to its 9 a.m state, and redo 49 minutes of work.  Then, you'll also need to redo the work that was performed after the deletion up to the time the error was discovered.

The full recovery model
If no transaction log backups are made between 9 a.m and 11 a.m, you would face the same situation as you would if the database had been using the simple recovery model.  In addition, your transaction log file would be much larger, as SQL Server will not truncate committed and checkpointed transactions until they have been backed up.
Assume that the transaction log is backed up every 30 minutes:
rm03_a
If a hardware failure occurs at 10:45 a.m, you would lose 15 minutes of work.  You can use the full database backup at 9 a.m, and apply the transaction logs to bring the database to its state at 10:30 a.m.  What if some critical data was deleted at 9:50 a.m?  Using the transaction log backup that was made at 10:00 a.m, you can restore the database to its state at 9:49 a.m.  You would still need to redo the work that was performed between the time of the deletion up to the time the error was discovered, as you cannot restore up to 9:49 a.m, skip the 9:50 a.m transactions, and restore the later transactions.  Admittedly, that would be great.
There are tools in the market that can simply reverse the changes created by user errors, while keeping the other transactions intact.  You still need transaction log backups to do that if the transaction is no longer in the active transaction log i.e. it has been backed up.

The bulk-logged recovery model
The situation with the bulk-logged recovery model is identical to the full recovery model if no minimally logged transactions are created in the database.  An example of a minimally logged transaction is a SELECT INTO operation.  Say that such a transaction occurred at 9:40 a.m.
rm04_a
This transaction would be minimally logged, which means that SQL Server only records the changed database pages arising from the transaction.  It does not log every insert into the new table.  Again, say that a critical table was deleted at 9:50 a.m.  What happens now?  You can no longer restore the database to its state at 9:49 a.m, as the transaction log backup created at 10:00 a.m cannot be used to restore to a specific point in time.  The best you can do is to restore the database to its state at 9:30 a.m.  Whenever a transaction log backup contains one or more minimally logged transactions, you cannot use that backup to perform a point in time restore.
rm05_a
Why then would anyone use the bulk-logged recovery model?  The main reason is performance.  Let's use the example of a SELECT INTO operation, say creating a large table from the results of a query.  If using the full recovery model, the details of every insertion into the new table is logged, and the transaction log will consume more space.  If using the bulk-logged recovery model, only details of the modified data pages are logged, allowing for better performance.  As we have seen, this comes at the expense of being able to perform a point in time restore using the transaction log.
The operations that are minimally logged are as follows (taken from SQL Server 2005 Books Online):
·Bulk import operations (bcp, INSERT ... SELECT * FROM OPENROWSET(BULK...), and BULK INSERT).
·text, ntext, and image operations using the WRITETEXT and UPDATETEXT statements when inserting or appending new data. Note that minimal logging is not used when existing values are updated.
·SELECT INTO operations.
·Partial updates to large value data types using the UPDATE statement's .WRITE clauses when inserting or appending new data. Note that minimal logging is not used when existing values are updated.
·If the database recovery model is set to either bulk-logged or simple, some INDEX DDL operations are minimally logged whether the operation is executed offline or online.
·DROP INDEX new heap rebuild (if applicable).

COPY_ONLY Backups with SQL Server

Problem
One issue with creating backups is that the LSNs (log sequence numbers) get stored in the backup files and these LSNs are referenced when you do a restore of your database. The reason the LSNs are stored with the backup file is to verify that the backup files are being restored in the proper sequence when you go to do your restores.  So if you try to restore your database files out of sequence you will get an error message from SQL Server such as the following:
The problem with having the LSNs stored with the backup file is that you can not do off schedule backups without affecting the LSNs of your regularly scheduled backups. 
Here is a scenario:
You normally run a full backup at midnight, transaction logs throughout the day and differentials every 3 hours.  Then you need to run a special full backup to load your test server.  If you then need to restore your production server you will need to use this most recent full backup, any differentials done after that and then any transaction log backups that were done after the differential.  Another approach to restore your database would be to restore your original backup and then just use only the transaction log backups, since the full backup does not affect the LSNs in the transaction log backup this will also work, but you loose the advantage of doing differential backups.
Solution
Starting with SQL Server 2005, a new backup option has been added that allows you to take full and transaction log backups in between your regularly scheduled backups without affecting the LSNs and therefore the sequence of files that would need to be restored.  Since Differential backups backup all data pages since the last full backup, these types of backups do not affect the LSNs and there is no difference when using the COPY_ONLY feature.
This new option is called COPY_ONLY.  To use this option you would write your backup command as follows:
BACKUP LOG AdventureWorks TO DISK='C:\AdventureWorks_log1.TRN' WITH COPY_ONLY
Now when we go to do a restore using the most recent full backup file along with all of the transaction logs except this COPY_ONLY version, the restore still works as planned.

Full and Transaction Log Backups

Here is a simple way of testing this out with just full and transaction log backups.  You can run the following backup commands and then the restore commands
-- step 1 USE master
GO
BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_full.BAK' WITH INIT
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log1.TRN' WITH INIT
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log2.TRN' WITH INIT

--step 2 RESTORE DATABASE AdventureWorks FROM DISK='C:\AdventureWorks_full.BAK' WITH NORECOVERY, REPLACE
--RESTORE LOG AdventureWorks FROM DISK='C:\AdventureWorks_log1.TRN' WITH NORECOVERY
RESTORE LOG AdventureWorks FROM DISK='C:\AdventureWorks_log2.TRN' WITH RECOVERY
At this point your restore will fail and the database will be in a LOADING mode. 
To test the same process out, but this time using the COPY_ONLY option, you can run the commands below.
-- step 1 USE master
GO
BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_full.BAK' WITH INIT
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log1.TRN' WITH INITCOPY_ONLY
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log2.TRN' WITH INIT
 
--step 2 RESTORE DATABASE AdventureWorks FROM DISK='C:\AdventureWorks_full.BAK' WITH NORECOVERY, REPLACE
--RESTORE LOG AdventureWorks FROM DISK='C:\AdventureWorks_log1.TRN' RESTORE LOG AdventureWorks FROM DISK='C:\AdventureWorks_log2.TRN' WITH RECOVERY
As you can see the restore process worked this time even though we had a backup that was not used for the restore process.

Full, Differential and Transaction Log Backups

Here is another way of testing full, differential and transaction log backups. 
--step 1  USE master 
GO 
BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_full.BAK' WITH INIT 
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log1.TRN' WITH INIT 
BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_diff.BAK' WITH INITDIFFERENTIAL
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log2.TRN' WITH INIT 
--run special full backup BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_full2.BAK' WITH INIT 
--resume normal backup process BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_diff2.BAK' WITH INITDIFFERENTIAL
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log3.TRN' WITH INIT 

--step 2  RESTORE DATABASE AdventureWorks FROM DISK='C:\AdventureWorks_full.BAK' WITH NORECOVERYREPLACE  RESTORE DATABASE AdventureWorks FROM DISK='C:\AdventureWorks_diff2.BAK' WITH NORECOVERY 
RESTORE LOG AdventureWorks FROM DISK='C:\AdventureWorks_log3.TRN' WITH RECOVERY
If we try to restore our original full backup, our latest full backup and any transaction log backup after the differential we get this error.
Msg 3136, Level 16, State 1, Line 1
This differential backup cannot be restored because the database has not been restored to the correct earlier state.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.
If we rerun the process, but this time use the COPY_ONLY option for our special full backup, the restore process works as planned.
--step 1 USE master 
GO 
BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_full.BAK' WITH INIT 
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log1.TRN' WITH INIT 
BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_diff.BAK' WITH INITDIFFERENTIAL
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log2.TRN' WITH INIT 
--run special full backup BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_full2.BAK' WITH INITCOPY_ONLY 
--resume normal backup process BACKUP DATABASE AdventureWorks TO DISK='c:\AdventureWorks_diff2.BAK' WITH INITDIFFERENTIAL
BACKUP LOG AdventureWorks TO DISK='c:\AdventureWorks_log3.TRN' WITH INIT 

--step 2  RESTORE DATABASE AdventureWorks FROM DISK='C:\AdventureWorks_full.BAK' WITH NORECOVERYREPLACE  RESTORE DATABASE AdventureWorks FROM DISK='C:\AdventureWorks_diff2.BAK' WITH NORECOVERY 
RESTORE LOG AdventureWorks FROM DISK='C:\AdventureWorks_log3.TRN' WITH RECOVERY