Backups e a janela de restauração¶
O histórico de um alvo é uma cadeia: backups completos em um agendamento e, entre eles, um fluxo de alterações contínuo (WAL do Postgres, binlog do MySQL). Qualquer segundo coberto por um backup completo e pelas alterações seguintes pode ser restaurado. Esse intervalo é a janela point-in-time.
gantt
dateFormat YYYY-MM-DD HH:mm
axisFormat %a %d
section Full backups
daily full :milestone, 2026-10-01 02:07, 0d
daily full :milestone, 2026-10-02 02:07, 0d
daily full :milestone, 2026-10-03 02:07, 0d
daily full :milestone, 2026-10-04 02:07, 0d
section Change stream
WAL / binlog segments :active, 2026-10-01 02:07, 2026-10-04 18:00
Backups completos¶
| Engine | Modo | Ferramenta | Restauração |
|---|---|---|---|
| Postgres 15–17 | physical (padrão) |
pg_basebackup -Ft -X fetch pelo protocolo de replicação |
base backup + replay do WAL até o segundo |
| Postgres 15–17 | logical |
pg_dump -Fc, um objeto por banco; exclusão de tabelas e exportações seletivas |
pg_restore, mais replay do WAL por uma cadeia física quando existir |
| MySQL 8.4 | logical |
mysqldump --single-transaction --source-data=2 (routines, events, triggers) |
carga + replay do binlog até o segundo |
Todo backup registra um inventário: bancos, tabelas, colunas, índices, estimativas de linhas e tamanhos, e a
versão da migração quando existe uma tabela de migrações. É isso que o console e o tenax diff comparam.
O fluxo de alterações¶
Cada alvo com recuperação point-in-time tem um streamer:
- Postgres: o receptor de WAL do próprio Tenax em um slot de replicação física (ADR 0005). O slot garante que nenhum WAL se perca enquanto o streamer reinicia.
- MySQL:
mysqlbinlog --read-from-remote-server --raw --stop-nevera partir da posição do binlog do último completo.
Os segmentos são enviados à medida que terminam, e o segmento ainda em gravação é enviado a cada partialInterval
(padrão 60 s), então o último minuto também pode ser restaurado. Cada segmento traz um resumo: commits, inserts,
updates e deletes por tabela, DDL e, opcionalmente, prévias de linhas mascaradas.
Se o stream quebrar (um slot se perde, um binlog é expurgado), o Tenax marca a cadeia como quebrada, alerta
(TenaxStreamChainBroken), inicia uma nova cadeia e faz um backup completo na hora (motivo chain-restart). A janela
antiga continua restaurável até o ponto da quebra.
Retenção¶
Os backups completos são mantidos por camadas; os segmentos só até onde a janela precisa; a coleta de lixo remove todo o resto, nunca algo fixado.
| Preset | Janela | Diário | Semanal | Mensal | Anual |
|---|---|---|---|---|---|
prod |
7 dias | 14 | 8 | 12 | 5 |
dev |
3 dias | 7 | 4 | 3 | 0 |
critical |
14 dias | 30 | 12 | 24 | 7 |
O primeiro completo confirmado de um dia é o diário desse dia; o de uma semana ISO, o semanal dela; e assim por
diante. Um backup pode ter várias camadas; nada é copiado. Fixações (tenax pin <id> --reason …) retêm um
backup independentemente das camadas. A GC grava o seu plano no bucket antes de excluir, exclui os manifestos antes
dos dados e limpa uploads órfãos e incompletos depois de um dia.
Formato de armazenamento¶
<store prefix>/<org>/<project>/<namespace>/<target>/
full/<backup-id>/manifest.json # written last: the commit marker
full/<backup-id>/data/<database>.zst.age # dumps or the base backup tar
full/<backup-id>/inventory.json.zst.age # also readable with the catalog key
full/<backup-id>/tags.json # tiers, pins, verification results
stream/…/<segment>.zst.age # WAL / binlog segments and their summaries
stream/position.json # the streamer's confirmed position
- Compressão: zstd no nível da política, uma vez, antes da criptografia; ativada por padrão
(ADR 0013).
compression.algorithm: nonearmazena os dados como estão. - Criptografia: cada objeto é criptografado com age no cliente para os destinatários do store. O bucket nunca vê texto em claro.
- Integridade: o tamanho e o SHA-256 de cada objeto estão no manifesto e são verificados em toda leitura.
- Commit: um backup só existe depois que
manifest.jsoné gravado. Uma falha antes disso deixa órfãos que a GC remove, nunca um backup que pareça completo.
Controle de carga¶
Os backups nunca disputam recursos às cegas com a produção: slots por host, por alvo e globais, um limite de banda,
uma prioridade, um jitter nos agendamentos e uma proteção de carga que adia um backup completo enquanto o servidor
tem conexões ativas demais, lag de replicação alto demais ou transações longas. Tudo isso é definido na
BackupPolicy.