você está aqui: Home  → Arquivo de Mensagens

Criando backups incrementais usando rsync e hardlinks

Colaboração: Marcelo Gonçalves Diotto

Data de Publicação: 09 de março de 2011

Há algum tempo estou testando ferramentas de backups para o linux, já testei várias ferramentas de backup e a que mais tinha me agradado até o momento era a rdiff-backup.

O rdiff-backup é uma ferramenta de backup diferencial que, na primeira vez que é executada realiza um espelho do diretório a ser copiado (algo similar ao rsync), nas próximas vezes que ele é executado ele realiza uma comparação entre o último backup feito e os dados atuais, realizando somente um backup das diferenças, com isso economiza-se espaço do servidor e pode-se ter a possibilidade de restaurar o backup de vários dias diferentes de seus dados, algo parecido com o que o TimeMachine do Mac faz.

O problema é que, embora eficiente, o rdiff-backup depende do software instalado tanto no cliente quando no servidor e normalmente suas versões não são compatíveis, sendo assim muitas vezes torna-se necessário baixar uma versão específica e compilá-la manualmente.

Outro problema é que a restauração de dados antigos não é são simples, é necessário utilizar o próprio rdiff-backup para isso e a restauração é um pouco demorada.

Não contente resolvi fazer alguns testes de backups diferenciais usando o rsync e links simbólicos. Com isso criei uma ferramenta denominada bkptool que é capaz de realizar backups diferenciais usando o recurso de hardlinks e com o rsync trabalhando pra fazer a sincronização.

O intuito da ferramenta é bem simples, basicamente você deve rodá-la passando três parametros, como no exemplo a seguir:

  # bkptool /var/www/ /backup/ www

O primeiro parâmetro indica a pasta a ser feito o backup

O segundo parâmetro indica o destino do backup (neste caso o mapeamento via NFS de meu NAS)

O terceiro é uma indicação do id do backup

Toda vez que o comando de backup for executado será criada uma pasta dentro do destino com o nome <id>-<ano>-<mes>-<dia>-<hora>-<minuto>-<segundo>. Para o comando do exemplo acima, seriam criadas pastas como:

  www.2011-02-24-14-16-46
  www.2011-02-25-13-48-29

Deste modo quando houver a necessidade de restaurar um backup é necessário simplesmente acessar a pasta do respectivo dia e copiar seu conteúdo de volta ao destino, sem a necessidade de programas adicionais.

Download do bkptool: http://www.diotto.net/downloads/bkptool

Segue abaixo o código fonte do mesmo:

  #!/usr/bin/env bash
  ORIGEM=$1
  DESTINO=$2
  NOME=$3
  QTDE=${4:-60}
  CONTADOR=0
  PLATFORM=$(uname)
  if [ "$ORIGEM" == "" -o "$DESTINO" == "" -o "$NOME" == "" ]; then
        echo "bkptool - Ferramenta de Realização de Backups Diferenciais"
        echo
        echo "$0    [qtde=30]"
        echo
        echo " - Origem            : pasta a ser feito o backup"
        echo " - Destino           : pasta de destino do backup"
        echo " - Id                : identificador do backup, deve ser apenas uma palavra"
        echo " - Qtde (opcional)   : quantidade de backups anteriores (alám do atual) que devem ser mantidos na pasta de destino (Padrão: 30)"
        echo
        exit 1
  fi
  if [ ! -d $ORIGEM ]; then
        echo "Pasta de origem \"$ORIGEM\" inexistente"
        exit 1
  fi
  if [ ! -d $DESTINO ]; then
        echo "Pasta de destino \"$DESTINO\" inexistente"
        exit 1
  fi
  ULTIMO_BACKUP=`find $DESTINO -maxdepth 1 -name "$NOME.*" | sort -nr | head -n 1`
  find $DESTINO -maxdepth 1 -name "$NOME.*" | sort -nr | tail -n +`expr $QTDE + 1` | while read antigo; do
        rm -rf "$antigo"
  done
  ID=`date +%Y-%m-%d-%H-%M-%S`
  BACKUP_ATUAL="$DESTINO/$NOME.$ID"
  echo "- Criando pasta $BACKUP_ATUAL"
  mkdir $BACKUP_ATUAL
  if [ "$ULTIMO_BACKUP" != "" ]; then
        echo "- Copiando pasta $ULTIMO_BACKUP para $BACKUP_ATUAL"
        if [ "$PLATFORM" == "FreeBSD" ]; then
                pasta=$(pwd)
                cd $ULTIMO_BACKUP
                pax -rwl -pe . $BACKUP_ATUAL
                cd $pasta
        else
                cp -al $ULTIMO_BACKUP/. $BACKUP_ATUAL
        fi
  fi
  echo "- Executando rsync de $ORIGEM para $BACKUP_ATUAL"
  rsync -a --delete $ORIGEM/ $BACKUP_ATUAL

Espero que esta ferramenta seja útil e também peço que, quem encontrar bugs ou tiver melhorias a sugerir me enviem para que eu implante em novas versões.



Veja a relação completa dos artigos de Marcelo Gonçalves Diotto