Getting SQL error 3159 when restoring a database
Solved Email & Outlook
RK
Rachel Kim
June 29, 2021
2 replies
8,280 views
Reviewed by moderators

Restoring last night's full backup over a broken database and SQL Server refuses with error 3159, the tail of the log for the database has not been backed up.

The database is broken, that is why I am restoring. Why is it protecting a log I want to overwrite?

Accepted Answer
Verified by Mariya Beckham, Database Moderator ยท Reviewed June 2021

It is protecting the transactions committed after last night's backup, which currently exist in exactly one place, that log you are about to overwrite. 3159 is SQL Server refusing to destroy the only copy of today's work without you saying so explicitly. Two exits, chosen by whether today's work matters:

Exit one, keep today's work, the usually correct answer: back up the tail first with BACKUP LOG yours TO DISK = 'path\tail.trn' WITH NORECOVERY, NO_TRUNCATE, the NO_TRUNCATE letting it read the log even with the database damaged. Then restore the chain: the full backup WITH NORECOVERY, any differentials and log backups WITH NORECOVERY in order, the tail backup last, then RESTORE DATABASE yours WITH RECOVERY. The database returns containing everything through the moment it broke, today included.

Exit two, discard today's work knowingly: RESTORE DATABASE yours FROM DISK = 'path\full.bak' WITH REPLACE, the REPLACE being the explicit consent 3159 was demanding. Correct when the database is a refreshed copy or a test system, or when the post backup transactions are genuinely worthless. On a production database, choosing REPLACE in a hurry converts a recoverable situation into a day of lost work, which is precisely the conversion 3159 exists to interrupt.

The refinement worth knowing for exit one: with the tail secured you also gain point in time choice, STOPAT on the final restore recovers to a chosen moment, the tool for when today's work includes the disaster itself, recovering to just before the bad deployment rather than through it.

Backed up the tail, restored the chain with it and today's morning orders came back with the database. Nearly typed REPLACE at 9am out of frustration, this error deserves more respect than it gets.