sexta-feira, 23 de abril de 2010

Fazendo Backup de um Repositório SVN

Um repositório do SVN é, na verdade, um banco de dados, embora tendo suas próprias peculiaridades. Assim, ele pode sofrer backup e pode ter seu conteúdo restaurado, total ou em parte. Este artigo ensina apenas a fazer backup do repositório. Há outros artigos nossos com outros tutoriais sobre o SVN que podem ser consultados: como configurar o SVN por túnel de SSH, os modos de configuração do SVN; configurando o SSH para atuar com o SVN.
Cada repositório SVN tem uma variável numérica que é incrementada a cada novo commit (efetivação), denominada "revision". Quando se faz backup, é interessante saber-se em qual número está o revision, ou para contabilizar a quantidade de alterações que foram enviadas, ou mesmo para saber se houve mudanças realmente desde o último backup. Para se obter o número da revisão mais recente, utilize o seguinte comando:

svnlook youngest [path e nome do repositório]

Exemplo:
$ svnlook youngest /var/svn/repo15
237
$

O comando anterior responde apenas o número da revisão, de forma que sua saída pode ser colocada diretamente em uma variável de um script. Para se obter mais informações sobre quem é o autor da última revisão e quando ele fez o commit, utilize o comando:

$ svnlook info /var/svn/repo15
fulano
2010-04-21 23:48:41 -0300 (Qua, 21 Abr 2010)
48
Esta é a mensagem que o autor deixou na revisão.

As linhas da resposta são: autor, data da revisão, número de caracteres da mensagem e a mensagem da revisão.
Ou, para inspecionar uma revisão anterior específica, use:

$ svnlook info /var/svn/repo15 -r 200
[sendo 200 a revisão antiga que se deseja inspecionar]

  • Backups Completos
O backup completo pode ser feito com o segunte comando:

$ svnadmin dump /var/svn/repo15 > repo15.r237

Isto fará o backup completo do repositório e o colocará no arquivo "repo115.r237", que pode ter o nome que você desejar. É claro que, quanto maior o repositório, mais lenta esta operação e maior será o arquivo (embora o arquivo de backup costume ser menor que o repositório em si). Muitas vezes, é isso mesmo que desejamos. No entanto, é possível se fazer backup de parte do repositório, a partir de números de revisão informados. Outra forma de backup pode ser:

Fazendo uma cópia direta do repositório para outro, que ficará idêntico ao primeiro:

svnadmin hotcopy /var/svn/repo15 /var/svn/repo16
[funciona exatamente como um comando "cp -r"]

Nesta opção, se você usa o Berkeley DB, você pode dar uma "limpada" nos arquivos de log que não são mais usados, diminuindo o tamanho do repositório. Para tanto use esta opção:

svnadmin hotcopy --clean-logs /var/svn/repo15 /var/svn/repo16

O novo repositório criado é completamente funcional e pode inclusive sofrer dump!!

  • Backups Parciais
Utilize o seguinte comando, para fazer backup de apenas uma faixa de revisões desejada:

[backup apenas da revisão 200]
$ svnadmin dump /var/svn/repo15 -r 200 > repo15.r200

[backup apenas da revisão 100 a 200]
$ svnadmin dump /var/svn/repo15 -r 100:200 > repo15.r100-200

Se o seu repositório é gigantesco, é possível que se crie vários arquivos de dump separados. Para tanto, deve-se usar a opção "--incremental". Exemplo:

$ svnadmin dump /var/svn/repo15 -r 0:1000 > dumpfile1
$ svnadmin dump /var/svn/repo15 -r 1001:2000 --incremental > dumpfile2
$ svnadmin dump /var/svn/repo15 -r 2001:3000 --incremental > dumpfile3

  • Recuperando o Backup
Como dizem as boas normas de segurança: não basta fazer o backup, mas é preciso se TESTAR O BACKUP!! Assim, vamos recuperar o backup para o repositório. Sem saber isso, de que valeria tê-lo, não é mesmo??

svnadmin load /var/svn/repo16 < repo15.r237

Isto fará um monte de commits, exatamente como seus autores o fizeram, alimentando o novo repositório com o conteúdo de dump do arquivo de backup.
Um backup direto pode ser feito sem a necessidade de arquivo de backup, da seguinte maneira:

svnadmin dump /var/svn/repo15 | svnadmin load /var/svn/repo16

Bom, espero ter ajudado com todas estas dicas... se este artigo te ajudou, atrapalhou, resolveu seu problema ou acabou de vez com sua vida, simplesmente: COMENTE!!!!

10 comentários:

Rafael Albani disse...

Muito bom o artigo, simples e objetivo, estava procurando a algum tempo um artigo que mostrasse o processo de forma direta, me ajudou muito.

O Pajé disse...

Muito obrigado, Rafael!! Fico feliz de ter podido ajudar!!

Anônimo disse...

Muito bom era o que eu precisava!

Elisa Zaroni Camargo disse...

Comentário, conforme pedido do autor.....

Post rápido, bem escrito e direto no ponto. Só fiquei uma dúvida: posso fazer um dump em uma instância e load em outra ? Ele consegue manter todo o histórico ?

E, para quê serve limpar as logs ? (essa eu vou ler no manual, mas se puder..., agradeço).

Tx a lot!

O Pajé disse...

Olá Elisa!!

Obrigado pelos elogios ao post!! Respondendo à sua pergunta:

Sim, é possível fazer o dump em uma instância e fazer o load em outra!!
Se o seu dump for completo, então o repositório onde será feito o load deverá ter sido recém-criado e, portanto, deverá estar vazio. Se o seu load for um "incremental", espera-se que o repositório de load esteja com o número de revisão imediatamente anterior à primeira revisão armazenada no arquivo de dump de incrementação.

Quanto à limpeza dos logs: o SVN tem o comportamento padrão de fazer registros de todas as operações em arquivos de log que ficam dentro dos repositórios. Assim, ele armazena não só commits, mas também updates, checkouts e outras operações que não são de escrita propriamente, gerando muitas vezes logs grandes, cheios de dados de checkouts e updates dos usuários. Imagine uma equipe enorme fazendo update toda hora, ou um SVN público de um projeto Open Source que sofre update e checkout do mundo inteiro a todo instante!! De vez em quando, o SVN até dá uma limpada mas, se você considera que estas informações não são úteis (ao menos não no disco, dentro do diretório do repositório), então é possível se livrar delas numa migração (um dump seguido de load), conforme mostrei acima. Isto pode te poupar espaço em disco e aumentar ligeiramente o desempenho do SVN, pois voltará a lidar com arquivos menores ou menor quantidade de arquivos, ou pelo menos acelerar a geração do dump e a carga do load.

Anônimo disse...

Gostei muito desse post, e como disse o Rafael logo no primeiro comentário, muito bom post - simples, direto ao assunto. Confesso que é preciso pensar um pouco para entender como os comandos funcionam e tal, mas essa é uma propriedade das coisas sucintas - demandam trabalho de entendimento. Me ajudou a dar os primeiros passos no assunto de dumps e loads. Preciso consertar um repo que tem uma revisão "quebrada" e estou tentando algumas idéias, como dump e recarga diferencial, pulando a versão defeituosa (svnadmin: Decompression of svndiff data failed). Muito obrigado!

O Pajé disse...

Muito obrigado pelo retorno, rapaz!! Fico feliz de ter podido ajudar!!
Com relação ao seu problema, se for possível, tente o seguinte:

1- Fazer o backup parcial, até a revisão imediatamente anterior ao commit quebrado;
2- Fazer o backup parcial, iniciando na versão imediatamente posterior ao commit quebrado e indo até o final;
(com isto pulamos uma revisão, a que está com problemas)
3- Fazer o load do primeiro backup;
4- Fazer um commit que substitua o commit quebrado;
5- Fazer o load do segundo backup.

Talvez isto o ajude a recuperar a saúde de seu repositório. Não apague nada antes de testar bastante. Faça o load sempre em um segundo repositório, ou seja, sem apagar ou danificar o original (ao menos até ter certeza de que tudo está certinho).

Fabio disse...

Nossa, valeu pelo retorno! De fato, é isso mesmo que eu estou tentando fazer e parece que está dando certo. A única coisa chata é que eu não consigo saber qual a operação exata foi feita no commit quebrado. Assim, quando eu retorno um dump que age sobre o que foi adicionado naquele commit quebrado, ele dá pau - mas nesse momento eu descubro como deveria ser, volto tudo, corrijo e avanço de novo... Eu olhei o log dos commits adiante e estou me guiando por eles.

Fabio disse...

Et voi-là! Resolvido! Apesar de aparentemente eu ter migrado meu repositório para uma versão mais nova, tudo está funcionando! Valeu pelo apoio!

O Pajé disse...

Beleza, Fabio!!

O caminho é este mesmo!! Parabéns pela resolução do problema!!
A versão nova não deve dar problemas com relação ao dump e ao load. Mas, tome cuidado se vc resolver voltar para uma versão antiga depois. E, claro, sempre bom fazer backups do repositório.