Prevenção virtual 102 : usando backups pessoais versionados (the even cheaper way)

Não, ao contrário do que você pensa, esse não é mais um daqueles posts chatos que falam sobre a importância de backups, puxa suas orelhas por você não estar em dia com eles e lhe deixa com uma sensação de estar fazendo algo errado e de que, a qualquer momento, poderá sofrer com isso.

Mesmo você sabendo que isso tudo é a mais pura verdade, ninguém precisa ficar lhe lembrando sobre isso a todo momento e lhe aporrinhando com esse assunto. Backup sempre é e sempre será esquecido. É comum (ou, ao menos, deveria ser) não esquecermos dos backups de nossos clientes, nossos servidores e de nossos sistemas mais importantes, mas nossos backups pessoais sempre acabam ficando esquecidos.

Por quê ? Simples : porque soluções que você simplesmente coloca para funcionar uma única vez e esquece, deixando que tudo seja feito de forma transparente, são difíceis de serem encontradas e, quando o são, não são das mais fáceis para serem implementadas nem compreeendidas.

Para resolver esse problema, eu escrevi um pequeno script shell simples que uso para meus backups pessoais. Funciona de maneira estremamente simples e me permite ter backups diários ou com periodicidades ainda menores (diversas vezes por dia, por exemplo) ocupando um espaço desprezível em relação ao que seria ocupado caso backups completos fossem utilizados e, de quebra, me permite restaurar a cópia de qualquer arquivo desejado, de uma data específica desejada, sem que seja necessário sair por aí procurando por inúmeras fitas ou sem que seja necessário que eu seja obrigado a usar soluções de backup que criam catálogos de backup e que possuam um uso mais complexo.

Facilidade, esse é o objetivo. Minha solução usa o famoso rsync para implementar backups diferenciais e, mais especificamente, faz uso da opção –link-dest do rsync para criar cópias posteriores dos backups utilizando hardlinks para os arquivos originais da primeira cópia do backup.

O script cria um diretório para cada uma de suas invocações, contendo o dia, mês, ano, hora, minuto e segundo de sua execução e inclui o backup nesse diretório. Dessa forma, você possui uma visão completa de todo o seu conteúdo de backup sob esse diretório representando esse momento no tempo. Sim, o conteúdo completo, tudo, sem mais nem menos, com a diferença de que não é a cada execução que tudo é realmente copiado para o novo diretório criado.

Somente os arquivos/diretórios modificados são criados e, para o restante, somente hardlinks para os arquivos originais criados como resultado da primeira execução do script são criados. O script mantém um arquivo de controle para saber qual o momento no tempo da última execução e ter uma base para saber a partir de qual ponto deve checar por modificações em suas próximas invocações.

O único detalhe é que, como hardlinks não funcionam entre dispositivos (ou seja, entre partições ou discos diferentes), todos os backups devem ser armazenados no mesmo disco ou partição de disco. Sempre, sem fugir dessa regra para não ter uma bela surpresa com espaço em disco astronômico sendo consumido sem necessidade.

Se interessou ? Ok, mão na massa então. Simplesmente copie o script postado em sua íntegra abaixo e grave-o com um nome qualquer desejado, torne-o executável e preencha o valor das variáveis target, sources e lastrunfile, ou seja, o local onde os backups serão criados, qual o conteúdo que será alvo de backup e qual a localizaçao do arquivo que conterá a informação do último momento no tempo em que a última execução do backup foi feita (ele é criado automaticamente na primeira execução do script), respectivamente.

O conteúdo completo do script é o seguinte :


#!/bin/bash

# Name : versioned-backup.sh
# Author : André Luís Lopes
# Description : A simple shell script which deploys a nice
# versioned backup solution based on rsync's
# hardlinking capability
# Version : 0.0.1
# License : GPL (General Public License) version 2

# Where's the rsync binary
rsync="/usr/bin/rsync"
# The miminal rsync options we absolutely want
rsyncminopts="-az"
# Our target directory, i.e, where we are going
# to dump everything
target="/backup/archives"
# A space separated list of directories we want to backup
sources="/etc /home"
# The current point-in-time (pit), constructed in
# the DD-MM-YYY-HH:MM:SS format
pit=$(date +%d-%m-%Y-%H:%M:%S)
# The file which will store the point-in-time
# information about our last snapshot run
lastrunfile="/backup/archives/lastrun"

# Ensure it works even when running for the very first
# time, as we create the target place where we are going
# to dump everything and the base directory to where we
# are going to hardlink further snapshots to
if [ ! -f $lastrunfile ] ; then
mkdir -p $target/$pit || true
echo $pit > $lastrunfile
for source in $sources ; do
$rsync $rsyncminopts $source $target/$pit
done
exit 0
fi

# As we are dealing with situations where we would need to
# be able to create snapshots every second and be able to
# differentiate between them, we create our point-in-time
# target directory for the current second
mkdir -p $target/$pit

# Create the snapshot of every source directory from the
# current point-in-time into our specific point-in-time
# directory and hardlink all the files and directories which
# where not modified since the last snapshot run
for source in $sources ; do
$rsync $rsyncminopts --link-dest=$target/$(cat $lastrunfile) $source $target/$pit/
done

# Store the identification of our last run into a non-volatile
# place so we can use it on further runs
echo $pit > $lastrunfile

Simplesmente execute o script de tempos em tempos, provavelmente agendado no crontab de um usuário que tenha permissões de ler os arquivos que sofrerão o backup e gravar no local onde o backup deverá ser armazenado (o root serve, mas não necessariamente precisa ser ele). É isso. Simples e fácil. Deixe o cron, o anacron ou seu agendador de tarefas preferido sendo executado e esqueça de suas preocupações com backup.

Lógico que o script pode melhorar bastante. Na verdade, tenho algumas idéias para melhorá-lo já a algum tempo, mas venho usando essa mesma solução a alguns meses sem maiores problemas e ela vem me atendendo bem, por isso nunca achei que fosse necessário melhorá-lo.

Funciona tão bem que algumas pessoas na empresa onde trabalho utilizam uma versão modificada dele, a qual eu modifiquei levemente para que o transporte ssh do rsync fosse utilizado, de forma que eu tivesse a mesma funcionalidade, mas em um ambiente em que o dispositivo que recebe o backup é uma partição de disco em um servidor remoto.

A imaginação é o limite. O que achou da solução ? Gostou ? Comente suas impressões e me deixe feliz ou profundamente triste caso minha solução seja muito tosca 🙂

Anúncios

18 comentários sobre “Prevenção virtual 102 : usando backups pessoais versionados (the even cheaper way)

  1. Gostei, mas eu uso o rsnapshot e ele faz “exatamente” isso. 😛

    Conhece?

    Eu particularmente gosto dele.

    Agora, o que queria mesmo era uma ferramenta integrada ao GNOME e bem interessante para fazer backups desse tipo: “versionados”.

    Tipo o Time Machine do Mac OS X hahahaha (nem tanto).

    Mas, você quem comprou um MacBook a pouco né? Bom, como é o Time Machine, que idéia poderíamos tirar dele para uma ferramenta de backup com interface gráfica (simples, não uma máquina do tempo)?

  2. Olá pessoal,

    Respondendo ao semente primeiro :

    Já tinha visto o nome do pacote rsnapshot vários vezes, mas nunca cheguei a testá-lo. Acabei fazendo o script e só descobri agora que você falou que o rsnapshot faz a mesma coisa 🙂

    Uma ferramenta gráfica que fizesse isso seria interessante, talvez um frontend GTK+ para o rsnapshot ? Não sei se existe, mas seria uma boa. De qualquer forma, eu gosto de deixar o script rodando em background e não me preocupar muito com ele, então interface gráfica nem é tão necessária nesse caso.

    Sobre o Time Machine, é um recurso presente somente no Mac OSX 10.5 (Leopard), que acabou de ser lançado, mas ao qual os brasileiros ainda não tiveram acesso (não legalmente, pelo menos), devido a incompetência da Apple Brasil em não querer vender o próprio software.

    Ou melhor, vender ela até quer vender, entregar é que é o problema. Só daqui a uns 20 dias, segundo o que aindei pesquisando.

    Respondendo ao faw :

    Antes de mais nada, é uma honra ter “o cara” comentando aqui 🙂 Posso até me dar um presente hoje por ter tido essa honra.

    Sobre o rsnaphot, como eu comentei na resposta para o semente, eu sabia da existência de um software com esse nome, já havia esbarrado diversas vezes com o pacote dele em pesquisas, mas nunca cheguei a testá-lo.

    Vou dar uma olhada nele quando tiver um tempo livre. Quem sabe ele me ofereça mais funcionalidades com mais facilidade e eu possa aposentar o meu pobre scriptzinho 🙂

  3. Com intenção ou não você acabou fazendo mais ou menos o que a Time Machine do OSX Leopard faz: cópias incrementais usando hardlinks pra manter uma imagem completa em cada backup, gastando pouco ou quase nenhum disco em cada execução.

    Claro que a camada do filesystem é bem diferente por causa das notificações de eventos, mas a idéia da Time Machine é essa. Interessante que chegou na mesma conclusão, gostei 🙂

  4. Olá caio 🙂

    Tudo bem ? Sobre como a Time Machine funciona, todos os reviews que li só falam superficialmente sobre o mesmo, não encontrei nada que explicasse mais o que existe “por baixo da carenagem”.

    Eu imaginava que algo usando backups incrementais fosse usado. De outra forma, ficaria impraticável devido a quantidade de espaço utilizado.

    Quem sabe a Time Machine não é só uma casca bonita por cima de um rsync ? 🙂 Brincadeira.

    Obrigado pelo comentário.

  5. Achei o seu script bacana, simples e funcional (sem contar que é útil).

    Só um detalhe: Porque a ultima linha do seu script é
    echo $pit > $lastrunfile
    se você já fez isso logo antes de executar o rsync?

    Eu estava pensando em implementar algo com o subversion mas ainda tenho que ver quais seriam os problemas que isso causaria (como por exemplo o tamanho da base dele etc) com o rsync não precisa isso mas também não pode-se usar hardlink para um backup efetivo em outro disco, certo?

    Em todo caso vou aproveitar a sua idéia que como já disse está muito boa e simples para o que preciso no momento.

    Só pra finalizar, meus parabéns novamente pela simples e útil ideia. 😉

  6. Olá Wellington,

    Obrigado pelo comentário. Sobre o script, o mesmo guarda as informações sobre a última execução no arquivo apontado pela variável $lastrunfile no final do script porque esse mesmo passo só é executado em outro local no script dentro de um if que só é executado caso o arquivo em questão não exista, ou seja, só é chamado na realidade na primeira execução do script (ou se o arquivo for apagado).

    Sobre usar Subversion, acredito que existiriam sim os problemas relacionados ao tamanho dos metadados do repositório a serem armazenados, a velocidade de execução e mais alguns outros que podemos não estar pensando nesse momento.

    Talvez usar git seria mais interessante para solucionar o problema da velocidade ? Não sei, seria necessário testar tudo para validar (ou invalidar) a idéia.

    Obrigado pelos elogios ao script.

  7. Backup versionado no linux

    Eu estava “extasiado” com o time machine do MAC OS X Leopard, e acabei encontrando essa postagem do blog do André Lopes através do BR-Linux, onde ele mostra um script dele que faz “praticamente” o mesmo tipo de backup do Leopard.
    ……

  8. Olá Sérgio,

    Não vejo problema algum em reproduzir o post, ainda mais com os devidos créditos, como você o fez.

    Só me resta agradecer pela divulgação da maneira correta como você fez e por me informar sobre isso.

    Obrigado pelo comentário.

  9. Para empresa o ideal é o backuppc tem uma interface web na qual pode ver a arvore de diretorios e mandar restaurar no logal original ou em um local alternativo, baixar como um arquivo .zip ou .tar, utiliza o rsync, ssh, samba e o tar para fazer o backup completo e incremental, também comprime os arquivos e realiza uma varredura no sistema para deletar arquivos duplicados e coloca-los em 1 só harlink, no caso se tiver 10 maquinas windows ou linux fazendo backup, o que for igual nas mesmas só tera o backup feito 1 unica vez.

  10. André]

    Muito bom seu tutorial. Estava procurando algo assim já tem algum tempo. Implementei aqui em meu servidor teu script com algumas motificações para me atender. mas não está funcionando. os hardlinks não estão sendo criados. estou fazendo backup de pastas dentro do home para um segundo hd. montado em /mnt/backup mas não está funcionando. eu entendi que eu não posso criar hard-links entre dispositivos. mas estou criando um backup principal pra esse hd montado em /mnt/backup.

    O que pode estar acontecendo???

  11. amigos, esse script, como ficaria para que o backup de um determinado diretorio fosse feito tão logo o pendrive seja inserido no pc?

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s