Restore Parcial e Point-in-Time no Microsoft SQL Server

Introdução

Quando ocorre uma falha, nem sempre você precisa (ou consegue) restaurar todo o banco imediatamente. Duas estratégias muito úteis são:

  • Point-in-Time Restore (PITR): voltar o banco a um instante exato usando STOPAT (opcionalmente com STANDBY para consultas durante a investigação).

  • Restore Parcial por Filegroups: restaurar primeiro o que é crítico (ex.: tabelas da aplicação principal) e liberar parcialmente o banco, concluindo os demais filegroups depois.

Requisito importante: para PITR você precisa estar em FULL ou BULK_LOGGED (não funciona em SIMPLE).


1) Point-in-Time Restore com STOPAT e STANDBY

Passo a passo (script pronto)

  1. Crie o banco e a tabela, insira o primeiro registro e faça o backup FULL:
CREATE DATABASE TestDB
go

CREATE TABLE TestDB.dbo.Clientes 
(ClienteID int not null primary key,
 Nome varchar(50),
 Telefone varchar(20))
go

INSERT TestDB.dbo.Clientes VALUES (1,'Jose','1111-1111')

BACKUP DATABASE TestDB 
  TO DISK = 'C:\_LIVE\Backup\TestDB.bak' 
  WITH format, compression, stats=5;

Gerar atividade no banco e fazer backup do log:

INSERT TestDB.dbo.Clientes VALUES (2,'Paula','2222-2222') -- 18:10
WAITFOR DELAY '00:02:00'
INSERT TestDB.dbo.Clientes VALUES (3,'Luana','3333-3333') -- 18:12
WAITFOR DELAY '00:02:00'
INSERT TestDB.dbo.Clientes VALUES (4,'Landry','4444-4444') -- 18:14

BACKUP LOG TestDB 
  TO DISK = 'C:\_LIVE\Backup\TestDB.trn' 
  WITH format, compression;

Restaure até momentos específicos usando STANDBY (banco fica read-only entre aplicações de log) e STOPAT:

RESTORE DATABASE TestDB_StopAt 
  FROM DISK = 'C:\_LIVE\Backup\TestDB.bak' 
  WITH FILE=1, NORECOVERY, REPLACE,
       MOVE 'TestDB'     TO 'C:\MSSQL_Data\TestDB_StopAt.mdf',
       MOVE 'TestDB_log' TO 'C:\MSSQL_Data\TestDB_StopAt_log.ldf';

RESTORE LOG TestDB_StopAt 
  FROM DISK = 'C:\_LIVE\Backup\TestDB.trn' 
  WITH STANDBY = 'C:\_HandsOn_AdmSQL\Backup\TestDB_StopAt.std',
       STOPAT  = '20250107 18:11:00.000';

RESTORE LOG TestDB_StopAt 
  FROM DISK = 'C:\_LIVE\Backup\TestDB.trn' 
  WITH STANDBY = 'C:\_HandsOn_AdmSQL\Backup\TestDB_StopAt.std',
       STOPAT  = '20250107 18:14:00.000';

RESTORE LOG TestDB_StopAt WITH RECOVERY;

Dica rápida:
NORECOVERY mantém o banco “em recuperação” para aplicar o próximo backup; RECOVERY finaliza; STANDBY deixa o banco somente leitura entre restaurações — ótimo para investigar se “aquela” alteração já apareceu antes de avançar.
• No fluxo de PITR: FULL (e opcionalmente o DIFF) com NORECOVERY, depois os LOGs na sequência até o STOPAT.

2) Restore Parcial por Filegroups (priorize o que é crítico)

Cenário

Você tem dois conjuntos de objetos (aplicações diferentes) separados em filegroups. Em um desastre, restaure primeiro o PRIMARY (obrigatório) e o(s) filegroup(s) críticos; depois, os demais — liberando parte do sistema mais cedo.

Observação: esse procedimento de restore parcial está disponível na edição Enterprise.

Passo a passo (script pronto)

Crie o banco com 3 filegroups e tabelas posicionadas em cada um:

CREATE DATABASE HandsOn
ON 
PRIMARY (NAME='HandsOn',     FILENAME='C:\MSSQL_Data\HandsOn.mdf'),
FILEGROUP FileGroup1 (NAME='FileGroup1', FILENAME='C:\MSSQL_Data\HandsOn_FileGroup1.ndf'),
FILEGROUP FileGroup2 (NAME='FileGroup2', FILENAME='C:\MSSQL_Data\HandsOn_FileGroup2.ndf')
LOG ON (NAME='HandsOn_log',  FILENAME='C:\MSSQL_Data\HandsOn_log.ldf');
go

USE HandsOn;
go
CREATE TABLE Tabela_Primary   (ID int identity, Nome varchar(100)) ON [PRIMARY];
CREATE TABLE Tabela_FileGroup1(ID int identity, Descricao varchar(100)) ON FileGroup1;
CREATE TABLE Tabela_FileGroup2(ID int identity, Descricao varchar(100)) ON FileGroup2;

INSERT INTO Tabela_Primary(Nome)            VALUES('Dados no FileGroup Primary');
INSERT INTO Tabela_FileGroup1(Descricao)    VALUES('Dados no FileGroup1');
INSERT INTO Tabela_FileGroup2(Descricao)    VALUES('Dados no FileGroup2');

Faça backups (incluindo tail-log com NORECOVERY para simular desastre e capturar as últimas transações):

BACKUP DATABASE HandsOn TO DISK = 'C:\_LIVE\Backup\HandsOn_FULL.bak' WITH format, compression;

-- (Opcional) Backups por filegroup:
BACKUP DATABASE HandsOn FILEGROUP = 'FileGroup1' TO DISK = 'C:\_LIVE\Backup\HandsOn_FileGroup1.bak' WITH format, compression;
BACKUP DATABASE HandsOn FILEGROUP = 'FileGroup2' TO DISK = 'C:\_LIVE\Backup\HandsOn_FileGroup2.bak' WITH format, compression;

-- Tail-log (não trunca o log)
BACKUP LOG HandsOn TO DISK = 'C:\_LIVE\Backup\HandsOn.trn' WITH format, compression, NORECOVERY;

Restaure parcialmente (PRIMARY primeiro), depois aplique o log e libere leitura/uso:

-- PRIMARY (obrigatório)
RESTORE DATABASE HandsOn_Parcial FILEGROUP = 'PRIMARY'
  FROM DISK = 'C:\_LIVE\Backup\HandsOn_FULL.bak'
  WITH PARTIAL, NORECOVERY,
       MOVE 'HandsOn'     TO 'C:\MSSQL_Data\HandsOn_Parcial.mdf',
       MOVE 'FileGroup1'  TO 'C:\MSSQL_Data\HandsOn_Parcial_FileGroup1.ndf',
       MOVE 'FileGroup2'  TO 'C:\MSSQL_Data\HandsOn_Parcial_FileGroup2.ndf',
       MOVE 'HandsOn_log' TO 'C:\MSSQL_Data\HandsOn_Parcial_log.log';

RESTORE LOG HandsOn_Parcial
  FROM DISK = 'C:\_LIVE\Backup\HandsOn.trn'
  WITH RECOVERY;

Complete os demais filegroups (bloqueie usuários durante cada etapa de restore do FG):

RESTORE DATABASE HandsOn_Parcial FILEGROUP = 'FileGroup1'
  FROM DISK = 'C:\_LIVE\Backup\HandsOn_FULL.bak'
  WITH NORECOVERY,
       MOVE 'FileGroup1' TO 'C:\MSSQL_Data\HandsOn_Parcial_FileGroup1.ndf';

RESTORE LOG HandsOn_Parcial 
  FROM DISK = 'C:\_LIVE\Backup\HandsOn.trn' 
  WITH RECOVERY;

RESTORE DATABASE HandsOn_Parcial FILEGROUP = 'FileGroup2'
  FROM DISK = 'C:\_LIVE\Backup\HandsOn_FULL.bak'
  WITH NORECOVERY,
       MOVE 'FileGroup2' TO 'C:\MSSQL_Data\HandsOn_Parcial_FileGroup2.ndf';

RESTORE LOG HandsOn_Parcial 
  FROM DISK = 'C:\_LIVE\Backup\HandsOn.trn' 
  WITH RECOVERY;

Nota operacional: durante o restore de cada filegroup, ninguém deve estar usando o banco; depois do passo, libere novamente.

Boas práticas e pegadinhas

  • MOVE nos RESTOREs: ao restaurar na mesma instância com outro nome, ajuste os caminhos/nomes físicos para evitar conflito com arquivos existentes. (Veja os MOVE nos scripts acima.)

  • Entenda NORECOVERY × STANDBY × RECOVERY antes de iniciar: evita travamentos e restaurações “travadas” no meio.

  • PITR exige FULL/BULK_LOGGED (não SIMPLE). Planeje sua política de backup/log pensando nisso.

  • Restore parcial: sempre comece pelo PRIMARY, depois os demais filegroups conforme a prioridade do negócio.

Fui, mas volto com mais SQL Server em breve!

✍️ Sobre o autor
O Prof. Landry é especialista em Microsoft SQL Server desde 1999, Microsoft Trainer, Professor Universitário e criador do canal SQL Server Expert no YouTube, com conteúdo técnico semanal para DBAs e profissionais de dados.

🚀 Quer aprender mais sobre SQL Server?
👉 Me acompanhe no LinkedIn e inscreva-se no canal para não perder nenhuma dica prática!

0
Subscribe to my newsletter

Read articles from SQL Server Expert directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SQL Server Expert
SQL Server Expert

O Prof. Landry Duailibe é especialista em Microsoft SQL Server desde 1999, Microsoft Certified Trainer, professor universitário e criador do canal SQL Server Expert no YouTube, onde compartilha conteúdo técnico semanal para DBAs e profissionais de dados. Já ajudou milhares de alunos a evoluírem suas habilidades com SQL Server e conquistarem melhores oportunidades na área de dados.