Point-in-time recovery é um método de restauração que reaplica um log de mudanças sobre um backup base para reconstruir o banco em qualquer segundo. O cenário para o qual ele existe não é a falha de hardware — disso a replicação cuida — mas o cenário humano: uma migração que corrompeu linhas às 14:32, um script que apagou o tenant errado. O PITR responde com a única coisa que ajuda: o banco exatamente como estava às 14:31:59.
Principais pontos
| Pergunta | Resposta |
|---|---|
| Snapshot | Uma fotografia — a restauração cai no momento em que foi tirado |
| PITR | Backup base + log de mudanças reaplicado — cai em qualquer segundo |
| RPO | Quanto de dado recente você pode perder — dado pela frequência de captura |
| RTO | Quanto a restauração pode demorar — dado pelo volume e pela mecânica |
| A divisão | O BaaS roda a mecânica; os objetivos e os simulados continuam seus |
O mecanismo, em uma sessão de trabalho
-- O log de mudanças é a matéria-prima: cada escrita commitada, em ordem.
-- Antes de um trabalho arriscado, dá para cravar um marcador nomeado nele:
SELECT pg_create_restore_point('before_pricing_migration');
-- Recuperação = backup base + replay, parado onde você mandar:
-- restaure o backup base tirado às 02:00
-- reaplique o log para a frente…
-- …e pare pouco antes do estrago:
-- recovery_target_time = '2026-08-05 14:31:59+00'
-- (ou recovery_target_name = 'before_pricing_migration')
-- Tudo que foi commitado antes do alvo existe; nada depois dele existe.
Isso é o write-ahead log fazendo dupla jornada: o mesmo registro ordenado que dá durabilidade às transações vira, quando arquivado continuamente, uma máquina do tempo. Bancos de documentos rodam a jogada idêntica com o oplog — capture o fluxo de operações, reaplique sobre um snapshot, pare sob demanda (o PostgreSQL chama isso de arquivamento contínuo; o MongoDB documenta a mesma arquitetura sobre snapshots de sistema de arquivos).
Depois de qualquer restauração, o passo de verificação do simulado (drill) acontece no nível da aplicação — confirme que a linha do tempo parou onde deveria:
// JavaScript / Node.js — Back4app JS SDK
// Restore drill: verify the restored data lines up with the incident timeline
const incident = new Date('2026-08-05T14:32:00Z'); // when the bad deploy hit
const latest = new Parse.Query('Order');
latest.lessThan('createdAt', incident);
latest.descending('createdAt');
const lastGood = await latest.first(); // newest order before the incident
const after = new Parse.Query('Order');
after.greaterThanOrEqualTo('createdAt', incident);
const leaked = await after.count(); // must be 0 on a clean PITR restore
console.log(`last good write: ${lastGood?.get('createdAt')}`);
console.log(`rows past the recovery target: ${leaked}`); // Flutter / Dart — Back4app Flutter SDK
// Restore drill: verify the restored data lines up with the incident timeline
final incident = DateTime.parse('2026-08-05T14:32:00Z'); // the bad deploy
final latest = QueryBuilder<ParseObject>(ParseObject('Order'))
..whereLessThan('createdAt', incident)
..orderByDescending('createdAt')
..setLimit(1);
final lastGood = await latest.query(); // newest order before the incident
final after = QueryBuilder<ParseObject>(ParseObject('Order'))
..whereGreaterThanOrEqualsTo('createdAt', incident);
final leaked = await after.count(); // must be 0 on a clean PITR restore
print('last good write: '
'${(lastGood.results?.first as ParseObject?)?.createdAt}');
print('rows past the recovery target: ${leaked.count}'); // iOS / Swift — Back4app Swift SDK
// Restore drill: verify the restored data lines up with the incident timeline
let incident = ISO8601DateFormatter()
.date(from: "2026-08-05T14:32:00Z")! // when the bad deploy hit
let latest = Order.query("createdAt" < incident)
.order([.descending("createdAt")])
.limit(1)
latest.first { result in // newest order before the incident
if case .success(let lastGood) = result {
print("last good write: \(String(describing: lastGood.createdAt))")
}
}
let after = Order.query("createdAt" >= incident)
after.count { result in // must be 0 on a clean PITR restore
if case .success(let leaked) = result {
print("rows past the recovery target: \(leaked)")
}
} // Android / Kotlin — Back4app Android SDK
// Restore drill: verify the restored data lines up with the incident timeline
val incident = Date(1754404320000L) // 2026-08-05T14:32:00Z, the bad deploy
val latest = ParseQuery.getQuery<ParseObject>("Order")
latest.whereLessThan("createdAt", incident)
latest.orderByDescending("createdAt")
latest.limit = 1
latest.findInBackground { lastGood, _ -> // newest order before the incident
println("last good write: ${lastGood?.firstOrNull()?.createdAt}")
}
val after = ParseQuery.getQuery<ParseObject>("Order")
after.whereGreaterThanOrEqualTo("createdAt", incident)
after.countInBackground { leaked, e -> // must be 0 on a clean PITR restore
if (e == null) println("rows past the recovery target: $leaked")
} Como uma restauração chega às 14:31:59
Duas propriedades caem do mecanismo. Primeira, o RPO é definido pela frequência de captura: logs enviados a cada poucos segundos significam segundos de perda máxima, independentemente de quando rodou o último snapshot. Segunda, o RTO é definido pela distância de replay: restaurar para as 23:00 a partir de uma base das 02:00 significa reaplicar 21 horas de escritas — razão pela qual sistemas com PITR continuam tirando snapshots frequentes, não por granularidade, mas para encurtar a pista.
Snapshots vs. PITR
| Dimensão | Só snapshots | PITR (base + replay de log) |
|---|---|---|
| Granularidade de restauração | Os momentos em que os snapshots rodaram | Qualquer segundo da janela |
| RPO típico | Horas (o intervalo da agenda) | Segundos a minutos |
| Custo de armazenamento | Baixo — n cópias | Maior — cópias + arquivo contínuo de log |
| Velocidade de restauração | Rápida — copiar de volta | Mais lenta — copiar + reaplicar |
| Encaixe com erro humano | Perde tudo desde o último snapshot | Perde quase nada antes do erro |
| Complexidade | Mínima | Real — arquivamento, ordenação, alvos |
De qual garantia de recuperação você realmente precisa?
| Se perder… é sobrevivível | Então você precisa de | Fique de olho em |
|---|---|---|
| Um dia de escritas | Snapshots noturnos | Tempo de retenção |
| Uma hora | Snapshots + incrementos frequentes | Se a agenda realmente dispara |
| Minutos ou menos | Captura contínua de log (PITR) | Lag do arquivamento — ele é o seu RPO |
| Nada, nunca | PITR + replicação síncrona | Custo e latência de escrita, precificados com honestidade |
Casos de uso comuns
- O deploy ruim. Uma migração ou hotfix corrompe dados no meio da tarde — restaure para o segundo anterior à subida.
- Deleção por dedo gordo. O tenant, a coleção ou o WHERE errado — recupere para logo antes de o comando rodar, muitas vezes num banco descartável para extrair só o que se perdeu.
- Ransomware e conta comprometida. Volte para antes de a invasão tocar os dados — com criptografia em repouso protegendo as próprias cópias arquivadas.
- Retenção para conformidade. Produtos regulados precisam provar recuperabilidade — janelas documentadas, restaurações testadas, simulados auditáveis.
- Ensaio pré-lançamento. O simulado de restauração como critério de release: times que já restauraram para um timestamp uma vez fazem isso com calma na noite em que importa.
Você deveria confiar nos backups padrão? Matriz de decisão
| O padrão basta quando… | Invista além dele quando… |
|---|---|
| Perder um dia de dados é chato, não fatal | Escritas são dinheiro — pedidos, lançamentos, reservas |
| O produto é pré-lançamento ou interno | Uma hora de perda é uma catástrofe de suporte |
| Os dados são reconstruíveis de outra fonte | O banco é a única fonte da verdade |
| Ninguém pediu garantias de recuperação | Um contrato ou regulador cita números de RPO/RTO |
| Você nunca precisou de uma restauração | Você já precisou — e foi tenso |
Seja qual for o que a plataforma oferece, três decisões continuam suas: o RPO que o seu produto sobrevive, o RTO que os seus usuários toleram e a cadência de simulados que mantém os dois números honestos — a disciplina que a orientação de planejamento de contingência do NIST formaliza assim: defina objetivos e depois teste contra eles.
Limitações e trade-offs
- Replicação não é recuperação. Réplicas replicam o erro em segundos; só backups alcançam o estado anterior a ele. Ferramentas diferentes, classes de falha diferentes.
- A janela é finita. O PITR alcança qualquer segundo — dentro da retenção. Estrago descoberto depois de a janela fechar é permanente; dimensione a retenção pelo tempo de detecção, não só pelo preço do armazenamento.
- Reaplicar leva tempo. Restaurações com muito log podem se arrastar; o seu RTO real é medido por simulados, não cotado por dashboards.
- Restaurações vêm inteiras. O PITR clássico reconstrói o banco num timestamp; extrair as linhas perdidas de uma tabela significa restaurar numa instância descartável e copiar de lá — planeje esse fluxo.
- Backup não testado é boato. Falhas silenciosas de export, credenciais expiradas, runbooks inexistentes — cada uma é invisível até um simulado ou um desastre encontrá-la. Simulados são mais baratos.
PITR e backups no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Os backups do banco gerenciado rodam em agenda sem configuração, e a restauração é uma operação de dashboard em vez de uma noite de arqueologia de logs — a metade de snapshots e mecânica deste artigo, absorvida pela plataforma. A metade que continua com você é a de decidir: as suas metas de RPO e RTO, as suas necessidades de retenção e o simulado trimestral em que as abas de código acima verificam que a linha do tempo restaurada é exatamente a que você pediu.
Perguntas frequentes
O que é point-in-time recovery em termos simples?
Uma restauração capaz de parar em qualquer instante, não apenas nos horários agendados de backup. A engine parte de um backup base e reaplica o log de mudanças — cada escrita commitada, em ordem — parando no segundo que você indicar. Em vez de perder tudo desde o snapshot da noite passada, você perde apenas o que aconteceu depois das 14:31:59, o segundo anterior ao incidente.
Qual a diferença entre snapshot e PITR?
Granularidade. Um snapshot é uma fotografia: a restauração cai exatamente no momento em que ele foi tirado, e tudo depois disso se perde. PITR é um filme: backup base mais captura contínua de log permitem parar a reprodução em qualquer ponto da janela de retenção. Snapshots são mais simples e mais baratos de manter; PITR transforma a recuperação de "qual noite?" em "qual segundo?".
O que é RPO e RTO?
Os dois números sobre os quais toda conversa de backup secretamente gira. RPO — recovery point objective — é quanto de dado recente você pode se dar ao luxo de perder, definido pela frequência de backup ou de envio de logs. RTO — recovery time objective — é quanto tempo a restauração pode levar, definido pelo volume de dados e pela mecânica do processo. Snapshots diários dão um RPO de horas; captura contínua de log encolhe isso para segundos.
Replicação substitui backup?
Não — replicação é disponibilidade, não recuperação. Uma réplica copia fielmente tudo o que o primário faz, inclusive o DROP TABLE que você rodou por engano; em segundos todas as cópias concordam sobre o estrago. Backups e PITR existem justamente para alcançar um estado *anterior* ao erro, que nenhuma replicação preserva. Você precisa dos dois, para classes diferentes de falha.
Com que frequência devo fazer backup do banco?
Trabalhe de trás para frente a partir do seu RPO. Se perder um dia de escritas é sobrevivível, snapshots noturnos bastam; se uma hora dói, acrescente incrementos mais frequentes; se minutos importam, você precisa de captura contínua de log — e aí a frequência dos snapshots passa a governar a velocidade de restauração, não a perda de dados. Seja qual for a agenda, o tempo de retenção decide até onde no passado os erros continuam corrigíveis.
Por que simulados de restauração importam?
Porque um backup não testado é uma hipótese, não um plano. Os simulados expõem as falhas que só aparecem na prática: exports quebrados em silêncio, restaurações que levam nove horas contra um RTO de uma, credenciais ausentes, passos não documentados. Um simulado trimestral — restaurar num ambiente descartável, verificar os dados, cronometrar o processo — converte a hipótese em procedimento ensaiado.
O que verificar depois de restaurar um banco de dados?
Verifique a linha do tempo primeiro: os registros mais novos devem ficar logo antes do alvo de recuperação, e nada deve existir depois dele. Depois verifique a integridade — contagens de linhas contra o esperado, invariantes críticas, referências que precisam resolver. Por fim verifique a aplicação: faça login, rode os fluxos principais, confirme que os jobs em segundo plano retomam limpos. Restaurações que "concluíram" ainda podem estar erradas das três formas.
Quem cuida dos backups num BaaS — a plataforma ou eu?
A mecânica é da plataforma: snapshots, captura de log, armazenamento, ferramental de restauração. Os objetivos continuam seus: escolher RPO e RTO para o seu produto, conhecer a janela de retenção, rodar simulados de restauração e manter um export independente se a política exigir. Um backend gerenciado remove o encanamento, não a responsabilidade de decidir o que é uma perda sobrevivível.