Sample Header Ad - 728x90

During an online piecemeal restore, is it possible to restore to a point-in-time?

3 votes
1 answer
365 views
I have a database (full recovery model) with multiple filegroups, that each have full and diff backups. I am able to replicate an online piecemeal restore (SQL Server 2019 Enterprise Edition) as it is described here: Example: Piecemeal Restore of Database (Full Recovery Model) However, when I add a STOPAT clause when restoring the last log backup, this only works for the primary filegroup. For all following filegroups I get either this message: > Msg 4342, Level 16, State 1, Line 161 Point-in-time recovery is not possible unless the primary filegroup is part of the restore sequence. Omit the point-in-time clause or restore the primary filegroup. When I try to restore the log without the STOPAT clause, I get this: > The supplied backup is not on the same recovery path as the database, and is ineligible for use for an online file restore. I was not able to find any restrictions about point-in-time recovery during online piecemeal restores, except for this part (found on Piecemeal Restores (SQL Server) ): > If a partial restore sequence excludes any FILESTREAM filegroup, point-in-time restore is not supported. You can force the restore sequence to continue. However the FILESTREAM filegroups that are omitted from your RESTORE statement can never be restored. To force a point-in-time restore, specify the CONTINUE_AFTER_ERROR option together with the STOPAT, STOPATMARK, or STOPBEFOREMARK option, which you must also specify in your subsequent RESTORE LOG statements. If you specify CONTINUE_AFTER_ERROR, the partial restore sequence succeeds and the FILESTREAM filegroup becomes unrecoverable. Since the database does not contain any filestream filegroups, this should not apply. Does anyone know if point-in-time recovery is possible in my scenario? --- Here is a minimal example to play with (not working): ------------------------------------------------------------------------ -- ONLINE PIECEMEAL RESTORE WITH POINT-IN-TIME RECOVERY ------------------------------------------------------------------------ --------------------------------- -- CREATE DB -- log, 2 filegroups (primary + A) and one table each --------------------------------- USE [master] GO CREATE DATABASE [RestoreTest] ON PRIMARY( NAME = 'PRIMARY', FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\RestoreTest.mdf' ), FILEGROUP A( NAME = 'RestoreTest_A', FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\RestoreTest_A.ndf' ) LOG ON( NAME = 'RestoreTest_log', FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\RestoreTest_Log.ldf' ) GO USE [RestoreTest] GO CREATE TABLE [Table1]( [X] INT ) ON [PRIMARY]; CREATE TABLE [Table2]( [X] INT ) ON [A]; GO --------------------------------- -- Backups --------------------------------- -- full backups of each filegroup BACKUP DATABASE [RestoreTest] FILEGROUP = 'PRIMARY' TO DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_Full.bak' WITH INIT BACKUP DATABASE [RestoreTest] FILEGROUP = 'A' TO DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_A_Full.bak' WITH INIT GO -- store current time for later point-in-time recovery WAITFOR DELAY '00:00:01' DECLARE @now DATETIME = (SELECT GETDATE()) EXEC sp_set_session_context 'stopat', @now; WAITFOR DELAY '00:00:01' --insert some data INSERT INTO [Table1] VALUES (1) INSERT INTO [Table2] VALUES (1) GO -- then take log backup BACKUP LOG [RestoreTest] TO DISK= 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_Log.bak' WITH INIT GO --------------------------------- -- RESTORE (point-in-time) --------------------------------- -- drop database USE [master] DROP DATABASE [RestoreTest] GO -- restore primary filegroup DECLARE @stopat DATETIME = (SELECT CAST(SESSION_CONTEXT(N'stopat') AS DATETIME)) RESTORE DATABASE [RestoreTest] FILEGROUP = 'PRIMARY' FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_Full.bak' WITH PARTIAL, NORECOVERY RESTORE LOG [RestoreTest] FILEGROUP = 'PRIMARY' FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_Log.bak' WITH RECOVERY, STOPAT = @stopat GO -- test SELECT [name], [state_desc] FROM sys.master_files WHERE [database_id] = DB_ID('RestoreTest') GO -- restore filegroup A (with STOPAT) DECLARE @stopat DATETIME = (SELECT CAST(SESSION_CONTEXT(N'stopat') AS DATETIME)) RESTORE DATABASE [RestoreTest] FILEGROUP = 'A' FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_A_Full.bak' WITH NORECOVERY RESTORE LOG [RestoreTest] FILEGROUP = 'A' FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_Log.bak' WITH RECOVERY, STOPAT = @stopat -- test SELECT [name], [state_desc] FROM sys.master_files WHERE [database_id] = DB_ID('RestoreTest') GO -- try again, restore filegroup A (without STOPAT) RESTORE DATABASE [RestoreTest] FILEGROUP = 'A' FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_A_Full.bak' WITH NORECOVERY RESTORE LOG [RestoreTest] FILEGROUP = 'A' FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\RestoreTest_Log.bak' WITH RECOVERY -- test SELECT [name], [state_desc] FROM sys.master_files WHERE [database_id] = DB_ID('RestoreTest') GO USE [master] DROP DATABASE [RestoreTest] GO Output: Processed 360 pages for database 'RestoreTest', file 'PRIMARY' on file 1. Processed 7 pages for database 'RestoreTest', file 'RestoreTest_log' on file 1. BACKUP DATABASE...FILE= successfully processed 367 pages in 0.021 seconds (136.346 MB/sec). Processed 8 pages for database 'RestoreTest', file 'RestoreTest_A' on file 1. Processed 3 pages for database 'RestoreTest', file 'RestoreTest_log' on file 1. BACKUP DATABASE...FILE= successfully processed 11 pages in 0.011 seconds (7.457 MB/sec). (1 row affected) (1 row affected) Processed 14 pages for database 'RestoreTest', file 'RestoreTest_log' on file 1. BACKUP LOG successfully processed 14 pages in 0.005 seconds (21.093 MB/sec). Processed 360 pages for database 'RestoreTest', file 'PRIMARY' on file 1. Processed 7 pages for database 'RestoreTest', file 'RestoreTest_log' on file 1. RESTORE DATABASE ... FILE= successfully processed 367 pages in 0.020 seconds (143.164 MB/sec). Processed 0 pages for database 'RestoreTest', file 'PRIMARY' on file 1. Processed 14 pages for database 'RestoreTest', file 'RestoreTest_log' on file 1. RESTORE LOG successfully processed 14 pages in 0.006 seconds (17.578 MB/sec). (3 rows affected) Processed 8 pages for database 'RestoreTest', file 'RestoreTest_A' on file 1. RESTORE DATABASE ... FILE= successfully processed 8 pages in 0.006 seconds (10.416 MB/sec). Msg 4342, Level 16, State 1, Line 116 Point-in-time recovery is not possible unless the primary filegroup is part of the restore sequence. Omit the point-in-time clause or restore the primary filegroup. Msg 3013, Level 16, State 1, Line 116 RESTORE LOG is terminating abnormally. (3 rows affected) Processed 8 pages for database 'RestoreTest', file 'RestoreTest_A' on file 1. RESTORE DATABASE ... FILE= successfully processed 8 pages in 0.005 seconds (12.500 MB/sec). Msg 3116, Level 16, State 1, Line 134 The supplied backup is not on the same recovery path as the database, and is ineligible for use for an online file restore. Msg 3013, Level 16, State 1, Line 134 RESTORE LOG is terminating abnormally. (3 rows affected)
Asked by Matthias L (93 rep)
Feb 10, 2023, 04:41 PM
Last activity: Feb 20, 2023, 10:22 AM