Restoring with T-SQL Code
A database backup is a regularly
scheduled occurrence, so if SQL Server's built-in Maintenance Plan
Wizard isn't to your liking, it makes sense to write some repeatable
code to perform backups and set up your own SQL Server Agent jobs.
However, unless the backup plan is only a full
backup, it's difficult to know how many differential backups or
transaction-log backups need to be restored; and because each backup
file requires a separate restore
command, it's difficult to script the recovery effort beforehand
without writing a lot of code to examine the msdb tables and determine
the restore sequence properly.
Note
The backupset
table in msdb database contains a row for each backup set. You can
query this table to find information on all the successful backups.
The RESTORE command restores from a full, differential, or transaction-log backup:
RESTORE DATABASE (or LOG) DatabaseName
Optional-File or Filegroup or Page
FROM BackUpDevice
WITH
FILE = FileNumber,
PARTIAL,
NORECOVERY or RECOVERY or STANDBY = UnDoFileName,
REPLACE,
STOPAT datetime,
STOPATMARK = ‘markname'
STOPBEFOREMARK = ‘markname'
To restore a full or differential backup, use the RESTORE DATABASE command; otherwise, use the RESTORE LOG for a transaction log. To restore a specific file or filegroup, add its name after the database name. The PARTIAL option specifies a partial restore that restores the primary filegroup and any specified secondary filegroups.
A backup set often contains several backup instances. For example, a backup set might consist of the following:
1: Full backup
2: Differential backup
3, 4, 5, 6: Transaction-log backups
7: Differential backup
8, 9: Transaction-log backups
The WITH FILE option specifies the backup to restore. If it's left out of the command, the first backup instance is restored.
If a password were created with the backup, the password is required to perform restore from the backup.
Note
Avoid using the password option because this feature will be removed in the future release of SQL Server.
To restore one or more pages, use PAGE = ‘file:page[,. . .n]’ where PAGE indicates a list of one or more files and pages; file indicates the file ID containing the page to be restored; page indicates the page id of the page to be restored in the file; and n indicates multiple pages can be specified.
The RECOVERY/NORECOVERY
option is vital to the restore command. Every time a SQL Server starts,
it automatically checks the transaction log, rolling back any
uncommitted transactions and completing any committed transactions.
This process is called recovery, and it's a part of the ACID properties of the database.
Therefore, if the restore has the NORECOVERY option, SQL Server restores the log without handling any transactions. Conversely, RECOVERY instructs SQL Server to handle the transactions. In the sequence of the recovery operation, all the restores must have the NORECOVERY option enabled, except for the last restore, which must have the RECOVERY option enabled.
Deciding between RECOVERY and NORECOVERY is one of the complications involved in trying to write a script to handle any possible future recovery operation.
The STANDBY option enables the recovery effects to be undone.
If the recovery operation includes a
transaction-log restore, the recovery can stop before the end of the
transaction log. The options STOPAT and STOPATMARK leave the end of the transaction log unrestored. The STOPAT accepts a time, and the STOPATMARK restores only to a transaction that was created with a named mark. The STOPBEFOREMARK option restores everything up to the beginning of the marked transaction.
The REPLACE option creates the database and its related files even if another database already exists with the same name.
The following script demonstrates an example of a restore sequence that includes a full backup and two transaction-log backups:
-- BackUp and recovery example
CREATE DATABASE Plan2Recover;
Result:
Command(s) completed successfully.
Continuing:
USE Plan2Recover;
CREATE TABLE T1 (
PK INT Identity PRIMARY KEY,
Name VARCHAR(15)
);
Go
INSERT T1 VALUES ('Full');
go
BACKUP DATABASE Plan2Recover
TO DISK = ‘e:\P2R.bak'
WITH
NAME = ‘P2R_Full',
INIT;
Result:
(1 row(s) affected)
Processed 168 pages for database ‘Plan2Recover', file ‘Plan2Recover'
on file 1.
Processed 6 pages for database ‘Plan2Recover', file ‘Plan2Recover_
log' on file 1.
BACKUP DATABASE successfully processed 174 pages in 0.800 seconds
(1.690 MB/sec).
Continuing:
INSERT T1 VALUES ('Log 1');
go
BACKUP Log Plan2Recover
TO DISK = ‘e:\P2R.bak'
WITH
NAME = ‘P2R_Log';
Result:
(1 row(s) affected)
Processed 6 pages for database ‘Plan2Recover', file ‘Plan2Recover_
log' on file 2.
BACKUP LOG successfully processed 6 pages in 0.113 seconds (0.393
MB/sec).
Continuing:
INSERT T1 VALUES ('Log 2');
go
BACKUP Log Plan2Recover
TO DISK = ‘e:\P2R.bak'
WITH
NAME = ‘P2R_Log';
Result:
(1 row(s) affected)
Processed 1 pages for database ‘Plan2Recover', file ‘Plan2Recover_
log' on file 3.
BACKUP LOG successfully processed 1 pages in 0.082 seconds (0.005
MB/sec).
Continuing:
SELECT * FROM T1;
Result:
PK Name
----------- ---------------
1 Full
2 Log 1
3 Log 2
(3 row(s) affected)
At this point the server is hit with a direct
bolt of lightning, and all drives are fried, with the exception of the
backup files. The following recovery operation goes through the full
backup and the two transaction-log backups. Notice the NORECOVERY and RECOVERY options:
-- NOW PERFORM THE RESTORE
Use Master;
RESTORE DATABASE Plan2Recover
FROM DISK = ‘e:\P2R.bak'
With FILE = 1, NORECOVERY;
Result:
Processed 168 pages for database ‘Plan2Recover', file ‘Plan2Recover'
on file 1.
Processed 6 pages for database ‘Plan2Recover', file ‘Plan2Recover_
log' on file 1.
RESTORE DATABASE successfully processed 174 pages in 0.168 seconds
(8.050 MB/sec).
Continuing:
RESTORE LOG Plan2Recover
FROM DISK = ‘e:\P2R.bak'
With FILE = 2, NORECOVERY;
Result:
Processed 0 pages for database ‘Plan2Recover', file ‘Plan2Recover' on
file 2.
Processed 6 pages for database ‘Plan2Recover', file ‘Plan2Recover_
log' on file 2.
RESTORE LOG successfully processed 6 pages in 0.028 seconds (1.586
MB/sec).
Continuing:
RESTORE LOG Plan2Recover
FROM DISK = ‘e:\P2R.bak'
With FILE = 3, RECOVERY;
Result:
Processed 0 pages for database ‘Plan2Recover', file ‘Plan2Recover' on
file 3.
Processed 1 pages for database ‘Plan2Recover', file ‘Plan2Recover_
log' on file 3.
RESTORE LOG successfully processed 1 pages in 0.004 seconds (0.122
MB/sec).
To test the recovery operation:
USE Plan2Recover;
Select * from T1;
Result:
PK Name
----------- ---------------
1 Full
2 Log 1
3 Log 2
(3 row(s) affected)
As this script shows, you can recover
using T-SQL, but in this case Management Studio beats code as the best
way to accomplish the task.