Chapter 15 · Backup, Restore, Recovery Models, and Point-in-Time Recovery

Restore Sequences, NORECOVERY/STANDBY, STOPAT, Piecemeal Restore, and Online Scenarios

Build deterministic SQL Server restore sequences with NORECOVERY, RECOVERY, STANDBY, MOVE and STOPAT while keeping recovery rehearsals isolated from the only good database.

Advanced190–240 minutespoint-in-time restore labSQL Server 2025 CU7 · 17.0.4065.4Compatibility 170 · Developer/ExpressSSMS 22.8.2 · Last reviewed August 2026

Learning outcomes

A backup set becomes useful only when you can assemble the correct restore sequence on a safe target. This lesson turns “restore the latest backup” into a deterministic algorithm: choose the target recovery point, select the correct full/differential base, apply every required log backup in order, keep the database non-operational while more log must be applied, and recover only when the intended endpoint is reached.

01

Construct full/differential/log restore sequences using NORECOVERY and an explicit final RECOVERY.

02

Use STOPAT to recover a disposable copy to a known time before a destructive change.

03

Explain when STANDBY creates a read-only between-log state and why it requires an undo file.

04

Relocate restored files safely with MOVE rather than overwriting the source database.

05

Distinguish offline restore from Enterprise-only online page/file/piecemeal scenarios.

1. NORECOVERY means “the sequence is not finished”

During restore, SQL Server copies backup pages, redoes logged changes, and eventually undoes incomplete transactions. WITH NORECOVERY deliberately postpones the final undo phase so additional differential or log backups can still be applied. Once you recover the database, you cannot continue applying older log backups to that recovery fork as though the sequence were still open.

Restore state What SQL Server allows Typical use
NORECOVERY / RESTORING No normal user access; additional backup sets can be applied Full → differential → log chain, AG/log-shipping initialization, PITR.
STANDBY Database is read-only between restores; undo information is written to a standby file Log shipping/read-only reporting or manual inspection between log restores.
RECOVERY Redo/undo completes and database becomes operational Final step after the selected recovery point is reached.

2. Build a source timeline that includes a deliberate mistake

The next script creates a source database whose logical file names are predictable, takes a full backup, records a safe update, captures a restore target timestamp, then performs a destructive delete and backs up the log. The target timestamp is persisted in master.dbo.ServiceHubRestoreMarker so the subsequent restore script can retrieve it even after batches change context.

sql · create a source timeline and capture the point before the destructive event
DECLARE @root nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultBackupPath'));IF @root IS NULL THROW 51000,'InstanceDefaultBackupPath is unavailable; choose a writable backup directory explicitly.',1;DECLARE @sep nchar(1)=CASE WHEN CHARINDEX(N'/',@root)>0 THEN N'/' ELSE N'\' END;IF RIGHT(@root,1) IN (N'/',N'\') SET @sep=N'';SELECT @root AS backup_root;USE master;IF DB_ID(N'ServiceHubRestoreTarget') IS NOT NULLBEGIN ALTER DATABASE ServiceHubRestoreTarget SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE ServiceHubRestoreTarget; END;IF DB_ID(N'ServiceHubRestoreSource') IS NOT NULLBEGIN ALTER DATABASE ServiceHubRestoreSource SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE ServiceHubRestoreSource; END;DROP TABLE IF EXISTS master.dbo.ServiceHubRestoreMarker;CREATE TABLE master.dbo.ServiceHubRestoreMarker(target_time datetime2(3) NOT NULL);CREATE DATABASE ServiceHubRestoreSource;ALTER DATABASE ServiceHubRestoreSource SET RECOVERY FULL;GOCREATE TABLE ServiceHubRestoreSource.dbo.WorkOrder(work_order_id int PRIMARY KEY,status varchar(20),amount decimal(12,2),changed_at datetime2(3));INSERT ServiceHubRestoreSource.dbo.WorkOrder VALUES(1,'OPEN',100,SYSUTCDATETIME()),(2,'ASSIGNED',250,SYSUTCDATETIME()),(3,'OPEN',400,SYSUTCDATETIME());GODECLARE @root nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultBackupPath'));DECLARE @sep nchar(1)=CASE WHEN CHARINDEX(N'/',@root)>0 THEN N'/' ELSE N'\' END;IF RIGHT(@root,1) IN (N'/',N'\') SET @sep=N'';DECLARE @full nvarchar(4000)=@root+@sep+N'ServiceHubRestoreSource_full.bak';DECLARE @log1 nvarchar(4000)=@root+@sep+N'ServiceHubRestoreSource_log1.trn';DECLARE @log2 nvarchar(4000)=@root+@sep+N'ServiceHubRestoreSource_log2.trn';BACKUP DATABASE ServiceHubRestoreSource TO DISK=@full WITH INIT,CHECKSUM;UPDATE ServiceHubRestoreSource.dbo.WorkOrderSET status='CLOSED',changed_at=SYSUTCDATETIME() WHERE work_order_id=1;BACKUP LOG ServiceHubRestoreSource TO DISK=@log1 WITH INIT,CHECKSUM;WAITFOR DELAY '00:00:02';INSERT master.dbo.ServiceHubRestoreMarker(target_time) VALUES(SYSUTCDATETIME());WAITFOR DELAY '00:00:02';DELETE ServiceHubRestoreSource.dbo.WorkOrder WHERE work_order_id=2; -- incidentBACKUP LOG ServiceHubRestoreSource TO DISK=@log2 WITH INIT,CHECKSUM;SELECT * FROM master.dbo.ServiceHubRestoreMarker;SELECT * FROM ServiceHubRestoreSource.dbo.WorkOrder ORDER BY work_order_id;

The source now lacks work order 2. The restore target will intentionally stop after work order 1 was closed but before work order 2 was deleted.

3. Restore to a new database with MOVE and STOPAT

Never rehearse recovery by overwriting the only known-good source. Restore to a separate name and separate physical files. MOVE maps the logical files in the backup to new physical paths; it is especially important when restoring to another instance whose default paths differ.

sql · restore the full and log sequence to the recorded point in time
DECLARE @root nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultBackupPath'));IF @root IS NULL THROW 51000,'InstanceDefaultBackupPath is unavailable; choose a writable backup directory explicitly.',1;DECLARE @sep nchar(1)=CASE WHEN CHARINDEX(N'/',@root)>0 THEN N'/' ELSE N'\' END;IF RIGHT(@root,1) IN (N'/',N'\') SET @sep=N'';SELECT @root AS backup_root;DECLARE @dataRoot nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultDataPath'));DECLARE @logRoot nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultLogPath'));DECLARE @dataSep nchar(1)=CASE WHEN CHARINDEX(N'/',@dataRoot)>0 THEN N'/' ELSE N'\' END;DECLARE @logSep nchar(1)=CASE WHEN CHARINDEX(N'/',@logRoot)>0 THEN N'/' ELSE N'\' END;IF RIGHT(@dataRoot,1) IN (N'/',N'\') SET @dataSep=N'';IF RIGHT(@logRoot,1) IN (N'/',N'\') SET @logSep=N'';DECLARE @full nvarchar(4000)=@root+@sep+N'ServiceHubRestoreSource_full.bak';DECLARE @log1 nvarchar(4000)=@root+@sep+N'ServiceHubRestoreSource_log1.trn';DECLARE @log2 nvarchar(4000)=@root+@sep+N'ServiceHubRestoreSource_log2.trn';DECLARE @target datetime=CONVERT(datetime,(SELECT TOP(1) target_time FROM master.dbo.ServiceHubRestoreMarker));DECLARE @mdf nvarchar(4000)=@dataRoot+@dataSep+N'ServiceHubRestoreTarget.mdf';DECLARE @ldf nvarchar(4000)=@logRoot+@logSep+N'ServiceHubRestoreTarget_log.ldf';RESTORE DATABASE ServiceHubRestoreTarget FROM DISK=@fullWITH MOVE N'ServiceHubRestoreSource' TO @mdf,     MOVE N'ServiceHubRestoreSource_log' TO @ldf,     NORECOVERY;RESTORE LOG ServiceHubRestoreTarget FROM DISK=@log1WITH NORECOVERY,STOPAT=@target;RESTORE LOG ServiceHubRestoreTarget FROM DISK=@log2WITH RECOVERY,STOPAT=@target;SELECT * FROM ServiceHubRestoreTarget.dbo.WorkOrder ORDER BY work_order_id;SELECT state_desc FROM sys.databases WHERE name=N'ServiceHubRestoreTarget';

Expected result: work order 1 is CLOSED, work order 2 still exists, and the target database is ONLINE. That proves the restore reached the business state represented by the target timestamp. It does not yet prove integrity, application compatibility, security mappings, Agent jobs or external dependencies—those validations belong to the recovery drill.

Wrong approach: recover after the full backup and then try to apply the logs.

RECOVERY completes undo and makes the database operational. The normal sequence must keep the target in RESTORING with NORECOVERY until the final log/endpoint is applied. Build the restore script before the incident instead of improvising while service is down.

4. STANDBY is read-only between log restores

STANDBY='undo-file' performs enough undo to expose the database read-only and writes undo information to a standby file so later log restores can reverse that undo and continue. That makes it useful in log-shipping/reporting patterns, but active readers must be disconnected when the next log is applied and the standby file itself is an operational dependency.

sql · STANDBY pattern for an alternate target — template only
-- RESTORE DATABASE ReportingStandby FROM DISK=@full--   WITH MOVE ..., NORECOVERY;-- RESTORE LOG ReportingStandby FROM DISK=@log1--   WITH STANDBY=N'<writable path>/ReportingStandby_undo.bak';-- SELECT ... FROM ReportingStandby.dbo.WorkOrder; -- read-only window-- RESTORE LOG ReportingStandby FROM DISK=@log2--   WITH STANDBY=N'<same undo file>';

5. Piecemeal/online restore is powerful but edition- and topology-sensitive

File and piecemeal restore let very large databases bring critical filegroups online before every archive filegroup has finished restoring. Microsoft’s current feature matrix keeps online page/file restore and several online restore scenarios in Enterprise-class capabilities. The free course path therefore teaches the restore sequence and filegroup design concept without requiring enterprise infrastructure.

Under FULL recovery, an offline file restore normally starts with a tail-log backup; online file restore has a different required log-backup sequence. Under SIMPLE, file restore is restricted to read-only secondary files. These are not details to discover during an outage.

sql · inspect restore/file metadata after the point-in-time drill
SELECT name,state_desc,recovery_model_desc,user_access_descFROM sys.databasesWHERE name IN (N'ServiceHubRestoreSource',N'ServiceHubRestoreTarget');GOSELECT DB_NAME(database_id) AS database_name,file_id,name,type_desc,       physical_name,state_descFROM sys.master_filesWHERE DB_NAME(database_id) IN (N'ServiceHubRestoreSource',N'ServiceHubRestoreTarget')ORDER BY database_name,file_id;GO-- RESTORE FILELISTONLY-- FROM DISK = N'<replace with the full-backup path printed by the lab>'; -- template

6. Production judgment

Production judgment. A restore runbook should contain the exact media order, logical-file mapping, target paths, tail-log decision, STOPAT/mark policy, encryption-key prerequisites, access-control change, expected restore duration and validation steps. Test on a disposable target with production-like storage and representative backup size. “The syntax worked on a 20 MB lab” is not an RTO guarantee for a multi-terabyte production database.

Check your understanding

  1. Why are intermediate restores normally performed WITH NORECOVERY?
  2. What does STOPAT protect you from in a point-in-time sequence?
  3. Why should a recovery drill restore to a different database or instance?
  4. What extra file does STANDBY require and why?
  5. Why is piecemeal/online restore not a universal free-edition lab?
Review the answers

1. It leaves the database in RESTORING without final undo so additional differential/log backup sets can be applied.

2. It prevents the restore sequence from replaying log records beyond the chosen recovery point, such as an accidental delete.

3. Overwriting the only good source converts a test into a destructive dependency. A separate target lets you validate before cutover.

4. An undo/standby file records changes needed to reverse the temporary undo when the next log backup is applied.

5. Online page/file and related restore capabilities are edition-sensitive and can require Enterprise-class features and large-database filegroup design.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.