tar na Prática: Backups Incrementais e Exclusões

tar na Prática: Backups Incrementais e Exclusões

O Que é um Backup Incremental com tar?

Conclusão: Ele arquiva apenas o que mudou desde a última execução. --listed-incremental registra um snapshot e calcula o diff a partir dele.

Depois de aprender a comprimir e extrair com Fundamentos do tar, três habilidades práticas vêm a seguir:

  • Backups incrementais (diferenciais): capturar apenas mudanças, sem uma cópia completa toda vez
  • Exclusões: ignorar node_modules, caches e outros ruídos
  • Controle de destino e caminho: definir exatamente onde e em que profundidade os arquivos são extraídos

Premissas deste guia

  • SO: Ubuntu (GNU tar)
  • tar --version reporta GNU tar (opções incrementais como --listed-incremental são específicas do GNU)
  • BSD tar (padrão no macOS) usa opções diferentes para alguns destes recursos

Por Que Usar --listed-incremental?

Conclusão: --listed-incremental rastreia exclusões e movimentações. --newer (comparação por mtime) não detecta exclusões e gera restaurações incorretas.

Existem duas formas de fazer backups incrementais:

Método Base Rastreia exclusões Recomendado
--listed-incremental (-g) arquivo de snapshot sim melhor
--newer / --after-date mtime (data modif.) não limitado

--newer apenas seleciona "arquivos mais novos que um determinado momento," então não consegue registrar arquivos excluídos desde a última execução. Na restauração, arquivos que você removeu reaparecem. --listed-incremental registra o estado do diretório em um arquivo de snapshot (convencionalmente com extensão .snar), reproduzindo o diff corretamente, incluindo exclusões.

--newer baseado em mtime serve para um diff rápido, mas para gerenciamento de gerações e restaurações precisas, use --listed-incremental.

Como Criar um Backup Incremental

Conclusão: Continue apontando -g para o mesmo arquivo de snapshot. A primeira execução é automaticamente nível 0 (completo); as seguintes se tornam nível 1 e acima (incrementais).

Nível 0 (backup completo)

Na primeira execução, quando o arquivo de snapshot não existe, você obtém automaticamente um backup completo.

$ tar -czg /backup/home.snar -f /backup/home-full.tar.gz /home/user/
  • -g /backup/home.snar: arquivo de snapshot (forma curta de --listed-incremental)
  • -c: criar / -z: gzip / -f: arquivo de saída
  • Após esta execução, home.snar contém o estado do diretório registrado

Nível 1 e acima (incremental)

Execute novamente com o mesmo arquivo de snapshot, e apenas as mudanças desde a execução anterior serão arquivadas.

$ tar -czg /backup/home.snar -f /backup/home-inc1.tar.gz /home/user/

home.snar é atualizado a cada execução e direciona o próximo diff. Use um nome de arquivo diferente (home-inc1, home-inc2...) por geração.

Quando você quer um backup completo toda vez

Aponte -g para /dev/null. Como o snapshot nunca é salvo (escritas em /dev/null desaparecem), toda execução é um backup completo de nível 0.

$ tar -czg /dev/null -f /backup/full.tar.gz /home/user/

Armazene o arquivo de snapshot separado dos dados de backup. Se perder o .snar, a cadeia de diff se quebra: a próxima execução pode silenciosamente se tornar um backup completo, ou seu procedimento de restauração falha.

Como Restaurar a Partir de Backups Incrementais?

Conclusão: Extraia na ordem das gerações, começando pelo nível 0. Adicione --listed-incremental na extração para que as exclusões também sejam reproduzidas.

Restaure na ordem exata em que os arquivos foram criados.

$ mkdir -p /restore
$ tar -xzg /dev/null -f /backup/home-full.tar.gz -C /restore
$ tar -xzg /dev/null -f /backup/home-inc1.tar.gz -C /restore
$ tar -xzg /dev/null -f /backup/home-inc2.tar.gz -C /restore
  • Passe /dev/null para -g na extração (o conteúdo do snapshot não é lido durante a restauração, mas a flag ativa o modo --listed-incremental)
  • Neste modo, arquivos excluídos em um incremento também são removidos do destino (uma restauração fiel da geração)
Inspecionando o conteúdo antes

Liste o conteúdo de um arquivo antes de extrair.

$ tar -tzf /backup/home-inc1.tar.gz | head

Um arquivo incremental inclui entradas de diretório junto com os arquivos alterados.

Como Especificar Padrões de Exclusão

Conclusão: Use --exclude=PADRAO para exclusões individuais e --exclude-from=ARQUIVO para uma lista. Coloque as opções antes dos caminhos de origem.

Excluir individualmente

$ tar --exclude='*.log' --exclude='node_modules' \
      -czf project.tar.gz project/
  • Padrões são globs (* ? [...]) comparados com os nomes dos membros no arquivo
  • Coloque --exclude antes do caminho de origem (project/); colocado depois, pode não ter efeito

Manter exclusões em um arquivo

Quando há muitas, use um padrão por linha.

$ cat > exclude.txt <<'EOF'
*.log
*.tmp
node_modules
.cache
EOF

$ tar --exclude-from=exclude.txt -czf project.tar.gz project/

A forma curta de --exclude-from é -X.

Opções integradas úteis

Opção Exclui
--exclude-vcs .git / .svn / CVS e outros metadados de VCS
--exclude-caches diretórios que contêm um arquivo CACHEDIR.TAG
$ tar --exclude-vcs --exclude='*.log' -czf src.tar.gz src/

Como Controlar o Destino e a Profundidade do Caminho?

Conclusão: -C define o diretório de destino, --strip-components=N remove componentes iniciais do caminho, e --one-top-level confina tudo sob um diretório pai.

Definir o destino (-C)

$ tar -xzf project.tar.gz -C /opt/app

A proteção básica contra arquivos se espalhando pelo diretório atual. Crie o destino antes.

Remover diretórios iniciais (--strip-components)

Quando um arquivo tem um nível de profundidade, como project-1.0/src/..., remova esse nível na extração.

$ tar -xzf project-1.0.tar.gz --strip-components=1 -C /opt/app

Isso remove project-1.0/ e extrai diretamente em /opt/app/src/.... Essencial para colocar um tarball de código-fonte do GitHub em um local fixo.

Confinar a um diretório pai (--one-top-level)

Para um arquivo cujos arquivos se espalham no nível superior, force tudo sob um único diretório.

$ tar -xzf messy.tar.gz --one-top-level=extracted

extracted/ é criado e tudo é extraído dentro dele (sem bagunca).

Na Prática: Um Padrão de Backup Diário

Conclusão: Execute um nível 0 semanal e um nível 1 diário. Combine uma lista de exclusão com um destino fixo para reduzir acidentes.

Template para copiar e colar

# Completo semanal (exclua o .snar primeiro se quiser resetar o snapshot)
tar --exclude-from=/etc/backup/exclude.txt \
    -czg /backup/home.snar \
    -f /backup/home-$(date +%Y%m%d)-full.tar.gz \
    /home/user/

# Incremental diario (continue reutilizando o mesmo .snar)
tar --exclude-from=/etc/backup/exclude.txt \
    -czg /backup/home.snar \
    -f /backup/home-$(date +%Y%m%d)-inc.tar.gz \
    /home/user/

# Restaurar (completo depois incremental; exclusoes reproduzidas)
tar -xzg /dev/null -f /backup/home-...-full.tar.gz -C /restore
tar -xzg /dev/null -f /backup/home-...-inc.tar.gz  -C /restore

O que não fazer

  • Extrair um incremento antes do backup completo (o completo sempre vem primeiro)
  • Manter o snapshot .snar apenas junto aos arquivos (ponto único de perda)
  • Extrair diretamente em um diretório de produção sem definir -C

Para agendamento, veja Fundamentos do cron; para planejamento de capacidade, veja No space left on device.

Próximas Leituras