Chapter 17 · Replication, Log Shipping, Distributed Availability, and Data Movement

Log Shipping Architecture, Restore Delay, DR Use Cases, and Failover Procedures

Use log shipping as a transparent backup-copy-restore DR pipeline with explicit restore delay, manual failover and measurable RPO/RTO.

Advanced190–235 minuteslog shipping DR labSQL Server 2025 CU7 · 17.0.4065.4Compatibility 170 · Developer simulationSSMS 22.8.2 · Last reviewed August 2026

Learning outcomes

Replication distributes data subsets. Log shipping instead keeps one or more warm copies of an entire database by repeatedly backing up the primary transaction log, copying each backup file and restoring it on a secondary. It is deliberately simpler than an Availability Group: no listener, no automatic role change, no cluster consensus. That simplicity can be valuable for disaster recovery, delayed-restore protection and version-transition scenarios.

01

Explain the backup, copy and restore jobs plus optional monitor server as a log-shipping pipeline.

02

Distinguish NORECOVERY and STANDBY secondaries and reason about intentional restore delay.

03

Measure RPO from the last restored log rather than from job success alone.

04

Execute a free single-instance manual log-shipping simulation without overwriting ServiceHubLab.

05

Plan manual failover/failback including tail-log and client-redirection responsibilities.

1. Log shipping is a scheduled log-chain pipeline

sql · record the local engine and data-movement feature context
SELECT SERVERPROPERTY('ProductVersion') AS product_version,       SERVERPROPERTY('ProductUpdateLevel') AS update_level,       SERVERPROPERTY('Edition') AS edition,       SERVERPROPERTY('EngineEdition') AS engine_edition,       SERVERPROPERTY('IsHadrEnabled') AS hadr_enabled,       SERVERPROPERTY('InstanceDefaultBackupPath') AS default_backup_path,       SERVERPROPERTY('ServerName') AS server_name;GOSELECT name, compatibility_level, recovery_model_desc,       is_published, is_subscribed, is_merge_published, is_distributorFROM sys.databasesWHERE name IN (N'ServiceHubLab', N'master', N'msdb') OR is_published=1 OR is_subscribed=1 OR is_merge_published=1 OR is_distributor=1;GO
Stage Runs where Failure symptom
Backup job Primary No new .trn files; primary log can grow if FULL model log backups stop.
Copy job Each secondary Backups exist at source but are absent/late at secondary staging path.
Restore job Each secondary Files are copied but last restored time/LSN stops advancing.
Monitor/alert job Monitor or local servers Threshold breach reveals that backup/restore cadence is outside objective.

SQL Server Agent normally schedules these jobs, which is why SQL Server 2025 Standard/Enterprise (and their free Developer counterparts) are the practical lab editions. Express does not support the built-in log shipping feature. The primary must use FULL or BULK_LOGGED recovery so transaction-log backups exist.

sql · inspect any configured log-shipping state in msdb
USE msdb;GOSELECT primary_database, backup_threshold, threshold_alert_enabled, last_backup_date, last_backup_fileFROM dbo.log_shipping_monitor_primary;SELECT secondary_database, restore_delay, restore_modeFROM dbo.log_shipping_secondary_databases;GO

2. A same-instance manual lab exposes the real mechanics

The following lab reproduces the essential backup→restore chain on one free Developer instance. It is not the SQL Server Agent log-shipping feature, but every restore rule is real. It uses the instance default backup directory so the path works on Windows or Linux when the SQL Server service can write there.

sql · create a disposable primary and establish a FULL recovery log chain
USE master;GOIF DB_ID(N'ServiceHubLS_Primary') IS NOT NULL DROP DATABASE ServiceHubLS_Primary;IF DB_ID(N'ServiceHubLS_Secondary') IS NOT NULL DROP DATABASE ServiceHubLS_Secondary;GOCREATE DATABASE ServiceHubLS_Primary;ALTER DATABASE ServiceHubLS_Primary SET RECOVERY FULL;GOUSE ServiceHubLS_Primary;CREATE TABLE dbo.CommitMarker(commit_id bigint PRIMARY KEY, note nvarchar(100), committed_at datetime2(3) DEFAULT SYSUTCDATETIME());INSERT dbo.CommitMarker(commit_id,note) VALUES (1,N'baseline');GODECLARE @dir nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultBackupPath'));DECLARE @full nvarchar(4000)=CONCAT(@dir, CASE WHEN RIGHT(@dir,1) IN ('/','\\') THEN '' WHEN CHARINDEX('\\',@dir)>0 THEN '\\' ELSE '/' END, 'ServiceHubLS_full.bak');DECLARE @sql nvarchar(max)=N'BACKUP DATABASE ServiceHubLS_Primary TO DISK=@p WITH INIT,CHECKSUM;';EXEC sys.sp_executesql @sql,N'@p nvarchar(4000)',@p=@full;GO

Backup/restore file names can collide across repeated labs; run only in a disposable environment. If your instance default backup path is NULL or not writable, choose a service-writable local directory and substitute it deliberately.

sql · take log backups after business commits
USE ServiceHubLS_Primary;INSERT dbo.CommitMarker(commit_id,note) VALUES (2,N'after full'),(3,N'before delay window');GODECLARE @dir nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultBackupPath'));DECLARE @log1 nvarchar(4000)=CONCAT(@dir, CASE WHEN RIGHT(@dir,1) IN ('/','\\') THEN '' WHEN CHARINDEX('\\',@dir)>0 THEN '\\' ELSE '/' END, 'ServiceHubLS_001.trn');DECLARE @sql nvarchar(max)=N'BACKUP LOG ServiceHubLS_Primary TO DISK=@p WITH INIT,CHECKSUM;';EXEC sys.sp_executesql @sql,N'@p nvarchar(4000)',@p=@log1;GO

In a real topology the copy job transports this file to the secondary. In this one-instance lab, restore the full backup to a different database in NORECOVERY, then apply the log. The explicit MOVE paths prevent the restore from colliding with the primary database files.

sql · restore the baseline and first log to a disposable secondary
USE master;GODECLARE @b nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultBackupPath'));DECLARE @d nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultDataPath'));DECLARE @l nvarchar(4000)=CONVERT(nvarchar(4000),SERVERPROPERTY('InstanceDefaultLogPath'));DECLARE @bsep nchar(1)=CASE WHEN CHARINDEX('\',@b)>0 THEN '\' ELSE '/' END;DECLARE @dsep nchar(1)=CASE WHEN CHARINDEX('\',@d)>0 THEN '\' ELSE '/' END;DECLARE @lsep nchar(1)=CASE WHEN CHARINDEX('\',@l)>0 THEN '\' ELSE '/' END;DECLARE @full nvarchar(4000)=CONCAT(@b,CASE WHEN RIGHT(@b,1) IN ('/','\') THEN '' ELSE @bsep END,'ServiceHubLS_full.bak');DECLARE @log1 nvarchar(4000)=CONCAT(@b,CASE WHEN RIGHT(@b,1) IN ('/','\') THEN '' ELSE @bsep END,'ServiceHubLS_001.trn');DECLARE @datafile nvarchar(4000)=CONCAT(@d,CASE WHEN RIGHT(@d,1) IN ('/','\') THEN '' ELSE @dsep END,'ServiceHubLS_Secondary.mdf');DECLARE @logfile nvarchar(4000)=CONCAT(@l,CASE WHEN RIGHT(@l,1) IN ('/','\') THEN '' ELSE @lsep END,'ServiceHubLS_Secondary_log.ldf');DECLARE @q nchar(1)=NCHAR(39);DECLARE @sql nvarchar(max)=    N'RESTORE DATABASE ServiceHubLS_Secondary FROM DISK=@full WITH MOVE N''ServiceHubLS_Primary'' TO N'    + @q + REPLACE(@datafile,@q,@q+@q) + @q    + N', MOVE N''ServiceHubLS_Primary_log'' TO N'    + @q + REPLACE(@logfile,@q,@q+@q) + @q    + N', NORECOVERY, REPLACE; RESTORE LOG ServiceHubLS_Secondary FROM DISK=@log1 WITH NORECOVERY;';EXEC sys.sp_executesql @sql,N'@full nvarchar(4000),@log1 nvarchar(4000)',@full=@full,@log1=@log1;SELECT name,state_desc FROM sys.databases WHERE name=N'ServiceHubLS_Secondary';GO

3. NORECOVERY, STANDBY and delayed restore

NORECOVERY keeps the database non-readable and ready for more log restores. STANDBY rolls back uncommitted work into a standby file and permits limited read-only access between restores; users can be disconnected when the next restore runs. A configured restore delay intentionally keeps the secondary behind. That worsens ordinary RPO but can create a window to recover rows before an accidental change is applied.

Choice Benefit Tradeoff
NORECOVERY Simplest continuous restore state No reads until recovery/failover.
STANDBY Read-only access between restore jobs Restore cycles can disconnect readers; same-major-version constraints apply in upgrade scenarios.
Delayed restore Protection window against quickly detected logical mistakes Secondary is intentionally stale; failover RPO includes the unapplied delay.
Wrong approach: “the copy job is green, therefore DR is current.”

The copy job can be current while restore is stopped. Measure last backup, last copied file and last restored file/time/LSN separately. Alert on the business freshness objective, not only job exit codes.

text · what to record before manual failover
1. Stop application writes to the old primary if it is reachable.2. Take a tail-log backup when possible and appropriate.3. Copy every remaining log backup to the secondary.4. Restore all remaining logs in sequence; recover the secondary only when promotion is authorized.5. Redirect the application/DNS/connection string manually—log shipping has no listener.6. Validate last business commit, integrity, security objects/jobs and backup ownership.7. Rebuild a reverse/failback data-movement plan; do not assume automatic resynchronization.
sql · clean up the disposable same-instance log-shipping simulation
USE master;GOIF DB_ID(N'ServiceHubLS_Secondary') IS NOT NULLBEGIN  ALTER DATABASE ServiceHubLS_Secondary SET SINGLE_USER WITH ROLLBACK IMMEDIATE;  DROP DATABASE ServiceHubLS_Secondary;END;IF DB_ID(N'ServiceHubLS_Primary') IS NOT NULLBEGIN  ALTER DATABASE ServiceHubLS_Primary SET SINGLE_USER WITH ROLLBACK IMMEDIATE;  DROP DATABASE ServiceHubLS_Primary;END;GO-- Backup files are intentionally not deleted by T-SQL. Remove only the lab files-- after confirming the exact paths and that no other restore drill needs them.

4. Production judgment

Production judgment. Log shipping is excellent when inexpensive warm DR and operational transparency are more valuable than automatic failover. It also supports restore delay. Its RTO includes detection, operator authorization, remaining-log restore, recovery and client redirection.

Check your understanding

  1. Why does log shipping require FULL or BULK_LOGGED recovery?
  2. What does the copy job prove?
  3. Why would an operator deliberately configure restore delay?
  4. What does STANDBY provide that NORECOVERY does not?
  5. Does log shipping redirect applications automatically after promotion?
Review the answers

1. Because the technology moves transaction-log backups; SIMPLE does not support the required log-backup chain.

2. Only that a backup file reached the secondary staging location—not that it was restored or that the secondary meets the RPO.

3. To preserve an older copy long enough to recover from quickly detected accidental changes or logical corruption.

4. Limited read-only access between restore operations, at the cost of reader disruption/standby-file management.

5. No. Failover and application redirection are manual orchestration responsibilities.

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.