Esta é (uma variante do) script que eu uso ( /home/pduck/bup.sh
):
#!/usr/bin/env bash
src_dir=/home/pduck
tgt_dir=/tmp/my-backups
mkdir -p $tgt_dir
# current backup directory, e.g. "2017-04-29T13:04:50";
now=$(date +%FT%H:%M:%S)
# previous backup directory
prev=$(ls $tgt_dir | grep -e '^....-..-..T..:..:..$' | tail -1);
if [ -z "$prev" ]; then
# initial backup
rsync -av --delete $src_dir $tgt_dir/$now/
else
# incremental backup
rsync -av --delete --link-dest=$tgt_dir/$prev/ $src_dir $tgt_dir/$now/
fi
exit 0;
Ele usa rsync
para copiar localmente os arquivos do meu diretório inicial para um local de backup, /tmp/my-backups
no meu caso.
Abaixo desse diretório de destino, é criado um diretório com o timestamp atual, por exemplo, /tmp/my-backups/2018-04-29T12:49:42
e abaixo desse diretório o backup desse dia é colocado.
Quando o script é executado novamente, ele percebe que já existe um diretório /tmp/my-backups/2018-04-29T12:49:42
(escolhe o diretório "mais recente" que corresponde ao padrão de registro de data e hora). Em seguida, ele executa o comando rsync
, mas desta vez com a opção --link-dest=/tmp/my-backups/2018-04-29T12:49:42/
para apontar para o backup anterior.
Este é o ponto real de fazer backups incrementais:
Com --link-dest=…
rsync não copia arquivos inalterados em comparação com os arquivos no diretório link-dest. Em vez disso, apenas cria hardlinks entre os arquivos atuais e os arquivos anteriores.
Quando você executa esse script 10 vezes, você obtém 10 diretórios com os vários carimbos de data / hora e cada um contém um instantâneo dos arquivos nesse momento. Você pode navegar pelos diretórios e restaurar os arquivos desejados.
O serviço de limpeza também é muito fácil: apenas rm -rf
do diretório de timestamp que você não deseja manter. Isso não removerá arquivos mais antigos ou mais recentes ou inalterados, apenas remova (diminua) os hardlinks. Por exemplo, se você tiver três gerações:
-
/tmp/my-backups/2018-04-29T...
-
/tmp/my-backups/2018-04-30T...
-
/tmp/my-backups/2018-05-01T...
e deletar o segundo diretório, então você perde o snapshot daquele dia, mas os arquivos ainda estão no primeiro ou no terceiro diretório (ou ambos).
Eu coloquei um cronjob em /etc/cron.daily
que diz:
#!/bin/sh
/usr/bin/systemd-cat -t backupscript -p info /home/pduck/bup.sh
Nomeie o arquivo backup
ou algo assim, chmod +x
, mas omita o sufixo .sh
(não será executado, em seguida). Devido a /usr/bin/systemd-cat -t backupscript -p info
, você pode assistir ao progresso via journalctl -t backupscript
.
Observe que essa solução rsync
exige que o diretório de destino esteja em um sistema de arquivos ext4
devido aos hardlinks.