Backup & Recovery from First Principles, Part 3: The Log Chain and How People Break It

Part 2 showed that log backups form a linked list: each backup’s first_lsn equals the previous backup’s last_lsn. Point-in-time restore works by walking that list. Break one link and every log backup after the break is useless until a new base re-anchors the chain. Today we break the chain on purpose, in the ways production systems break it by accident.

Illustration of a numbered chain of log backup links with one broken red link, and a woman holding a replacement link, representing a broken SQL Server log backup chain

This is part 3 of the backup and recovery series (part 1: recovery models). Demos ran on SQL Server 2019 (CU32) and behave identically on SQL Server 2025 (RTM).

Break #1: Switching to SIMPLE (Even Briefly)

The classic. Someone flips a database to SIMPLE recovery to “fix” a full log file, then flips it back, and believes everything is fine because both commands succeeded:

The switch to SIMPLE truncated the log and severed the chain; the switch back to FULL put the database into the pseudo-simple state from part 1. At least error 4214 is loud. Your monitoring should treat a failing log backup job as a page-someone event, because from this moment until the next full or differential backup, point-in-time restore is impossible: log backup failures are exactly as dangerous as they sound.

The repair is a new base. A full backup works; so does a differential if the old full is still valid, because a differential can re-anchor a log chain, which is a genuinely useful trick on very large databases where a full takes hours.

Break #2: The Rogue Backup Tool

Anything that takes a non-copy-only log backup consumes log records. If a third-party agent, a well-meaning colleague, or a second backup product takes a log backup to its own destination, your primary log backup sequence has a hole in it: the records went into a file you may not even know exists. The chain itself is intact, but part of it lives somewhere else. Restore-time symptom:

Error 4305 is SQL Server telling you the exact LSN gap. Find the missing range in msdb.dbo.backupset (or the other tool’s catalog) by hunting for a log backup whose range covers the LSN it names. Prevention: exactly one product owns log backups; everything else uses COPY_ONLY, which is part 4’s subject.

A special case of this break: BACKUP LOG ... TO DISK = 'NUL'. It consumes the log records and writes them to nowhere. The chain is not merely relocated, that range of it is gone. There is no legitimate reason to do this outside of a throwaway test system.

Break #3: Restoring a Snapshot, Reverting a VM

Reverting a database from a database snapshot, or reverting the whole VM from a hypervisor snapshot, rewinds the database to an earlier LSN. The backup history in msdb (or your backup tool) now describes a future that no longer exists. The next log backup may even appear to succeed, but the chain across the revert boundary is not restorable. After any revert: take a full or differential backup immediately and treat everything before it as history.

Detecting a Broken Chain Before You Need It

The moment the chain breaks, this query starts telling the truth:

A database in FULL recovery with last_log_backup_lsn IS NULL has no log chain: it is either brand new, pseudo-simple, or freshly broken. In our demo, immediately after the SIMPLE flip:

I published an alerting approach for FULL-recovery databases with no log backups that catches this class of problem; pair it with a check on log backup job failures and you have both ends covered.

The Tail of the Log

The chain has one more link that does not exist as a file yet: the log records generated since the most recent log backup. That is the tail. In a disaster where the data files are lost but the log file survives, backing up the tail first is the difference between restoring to “right now” and restoring to “whenever the last log backup ran”:

NO_TRUNCATE lets the backup proceed even when the database is damaged or offline; NORECOVERY puts the database into the restoring state, drawing a clean line under the timeline.[1] Make taking the tail backup the literal first step of your disaster runbook, before anyone touches restore commands, because several restore paths (like WITH REPLACE) will happily destroy the tail if you skip it. For broader disaster planning context, see the HA/DR options field guide.

Chain Rules, Condensed

  • Only log backups walk the chain forward; full and differential backups do not consume log or break the chain.[2]
  • SIMPLE recovery, even for a moment, severs the chain. Re-anchor with a full or differential immediately.
  • One tool owns log backups. Everything else takes COPY_ONLY.
  • Monitor for last_log_backup_lsn IS NULL and for failing log backup jobs. Both are restore-blocking conditions, not warnings.
  • In a disaster: tail-log backup first, questions later.

Part 4 covers the chain-safe way to take an extra backup whenever you want one: COPY_ONLY, and a deployment-rollback pattern built on it.

Broken a log chain in a way I did not list? I collect these. Comments below, or find me on Bluesky or LinkedIn.

References

  1. Tail-Log Backups (SQL Server) – Microsoft Learn. When a tail-log backup is required and the NO_TRUNCATE / NORECOVERY options.
  2. Debunking a couple of myths around full database backups – Paul Randal, SQLskills. Proof that full backups do not truncate the log or affect the log backup chain.