Mostrar mensagens com a etiqueta Backup. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Backup. Mostrar todas as mensagens

quinta-feira, 29 de outubro de 2020

Error Rapid recover - CBT is not currently enabled



Problem

Exception chain:
  • 'Server' validation has failed. CBT is not currently enabled. This feature will be enabled during the protection process, all ESXi snapshots will be removed. Protection is not allowed.
  • One or more errors occurred.

Resolution

To enable or disable CBT on a virtual machine, perform the appropriate steps given for enabling or disabling: 

Note: Ensure that the virtual machine is powered off before performing these steps.
To enable CBT in a virtual machine:

1. Power off the virtual machine.
2. Right-click the virtual machine and click Edit Settings.
3. Click the Options tab.
4. Click General under the Advanced section and then click Configuration Parameters. The Configuration Parameters dialog opens.
5. Click Add Row.
6. Add the ctkEnabled parameter and then set its value to true.
7. Click Add Row, add scsi0:0.ctkEnabled, and set its value to true.
Note: scsi0:0 in scsi0:0.ctkEnabled indicates the SCSI device assigned to the hard disk that is added to the virtual machine. Every hard disk added to the virtual machine is given a SCSI device that appears similar to scsi0:0, scsi0:1, or scsi 1:1. CBT is enabled (or disabled) individually on each disk.

8. Power on the virtual machine.
9. In the home directory of the virtual machine, verify that each disk having CBT enabled has also a vmname-ctk.vmdk file.

terça-feira, 25 de outubro de 2011

Backup e restauração de arquivos


Fonte: http://www.devin.com.br/backup-e-restauracao-de-arquivos/
Autor:Hugo Cisneiros (Eitch)

Dicas sobre como fazer backups e organizá-los no Linux. Ahhh… Backups, só precisamos dele quando não temos!
A maioria das pessoas costuma não pensar muito em backups, até o momento que acontece alguma coisa com o sistema e os dados são perdidos. Fazer backup é sempre bom, mesmo que for um backup bem simples: melhor prevenir.
Quando se faz uma cópia dos arquivos mais importantes do sistema, vale a pena ressaltar que uma política de backup tem que ser definida antes de tudo. Para que os backups sejam eficientes, é necessário que as cópias dos dados se espalhem o máximo possível. Destinos de backups:
  • Coloque os dados em um disco separado (HD removível ou não);
  • Grave cópias em uma mídia externa (CD, DVD, fita);
  • Transfira cópias pela rede para sistemas que estejam longe;
O terceiro item seria a melhor alternativa, quando se tem uma alta capacidade de transferência entre um destino e outro.
Para fazer os backups, utilizaremos o comando tar. Exemplo:
# mkdir -p /var/lib/backup
# cd /var/lib/backup
# tar -cjf maquina-backup-full-20030212.tar.bz2 /etc /var/named /var/log

Armazenamos os arquivos dos diretórios /etc, /var/named e /var/log no arquivo maquina-backup-full-20030212.tar.bz2, compactado com bzip2. Com este arquivo, teremos um backup completo dos três diretórios especificados.

Mais um exemplo:
# tar -cjf maquina-home-full-20030212.tar.bz2 /home

Este outro arquivo terá o backup do diretório /home, ou seja, o diretório dos usuários do sistema.

Agora vamos supor que algum programa alterou o conteúdo do diretório /etc, adicionando um arquivo chamado teste e modificando o arquivo crontab. Para não ter que fazer um backup completo novamente, podemos incrementar este backup somente com as modificações feitas recentemente. Para isso eu utilizo o seguinte comando:
# find /etc /var/named /var/log -mtime -1 -type f -print | \
  tar -cjf maquina-backup-incremental-20030212.tar.bz2 -T -

O comando find vai procurar por arquivos modificados numa faixa de 1 dia (usado para backups incrementais diários) e armazená-los no arquivo maquina-backup-incremental-20030212.tar.bz2.

Agora um backup feito com os arquivos modificados numa faixa de uma semana:
# find /etc /var/named /var/log -mtime -7 -type f -print | \
  tar -cjf maquina-backup-incremental-20030212.tar.bz2 -T -

Backup Remoto


Fonte: http://www.devin.com.br/backup_remoto/
Autor:Hugo Cisneiros (Eitch)
Um tutorial que explica como fazer um backup simples de arquivos no sistema (backups completos ou diferenciais) e armazenar em um servidor remoto via FTP.

Nem sempre as pessoas pensam em backup, só quando acontece alguma coisa com seu sistema. Um backup sempre é bom, mesmo que for bem simples. Vou apresentar através deste manual algumas formas de se fazer backup de arquivos do sistema Linux, opcionalmente armazenando estas cópias em um servidor remoto via FTP. Com isso os administradores de redes podem centralizer os backups em uma máquina, para depois armazenar ou em uma fita dat, ou em cd-rom, ou seja lá o que for.
Para fazer os backups, utilizaremos o clássico comando “tar“, que serve justamente para isso: armazenar arquivos em um arquivo. Vamos primeiro criar um exemplo de arquivo de backup:
# tar -cf maquina-backup-full-20030212.tar /etc /var/named /var/log
# bzip2 maquina-backup-full-20030212.tar

O que fiz foi armazenar os arquivos dos diretórios “/etc“, “/var/named” e “/var/log” no arquivo maquina-backup-20030212.tar, e depois compactá-lo no formato bzip2 (uma compactação melhor, mas que requer mais processamento), gerando então o arquivo “maquina-backup-20030212.tar.bz2“. Este mesmo comando pode ser feito em uma linha só:
# tar -jcf maquina-backup-full-20030212.tar.bz2 /etc /var/named /var/log

Com este arquivo, teremos um backup completo dos três diretórios especificados. Vamos à mais um exemplo:
# tar -zcf maquina-backup-full-20030212.tar.gz /etc /var/named /var/log
# tar -zcf maquina-home-full-20030212.tar.gz /home

Aqui eu criei dois arquivos. Um arquivo contém o backup que criamos anteriormente, e outro arquivo terá o backup do diretório “/home“, ou seja, o diretório dos usuários do sistema. A diferença aqui é que eu usei a opção “z” e não a “j“. Isso quer dizer que o tar vai usar o programa gzip ao invés do bzip2.

Agora vamos supor que eu alterei o conteúdo do diretório “/etc“, adicionando um arquivo chamado “teste” e modificando o arquivo “crontab“. Para não ter que fazer um backup total novamente, eu posso incrementar este backup somente com as modificações feitas. Para isso eu utilizo o seguinte comando:
# find /etc /var/named /var/log -mtime -1 -type f -print | \
tar zcvf maquina-backup-incremental-20030212.tar.gz -T -

Aqui o Linux vai procurar por arquivos modificados numa faixa de 1 dia (usado para backups incrementais diários) e armazená-los no arquivo “maquina-backup-incremental-20030212.tar.gz“. Vejamos agora um backup feito com os arquivos modificados numa faixa de uma semana:
# find /etc /var/named /var/log -mtime -7 -type f -print | \
tar zcvf maquina-backup-incremental-20030212.tar.gz -T -

Agora se você quiser automatizar, e poupar trabalho, use para a nomeação do arquivo o comando “date“, gerando assim a data no arquivo. Veja o exemplo dessa compactação:
# tar zcf backup-full-`date +%Y%m%d`.tar.gz /etc
# ls
backup-full-20030212.tar.gz

Agora que você já aprendeu a fazer os backups, vamos armazená-lo remotamente. Eu assumo que você já tenha configurado um servidor FTP em outra máquina, se você ainda não fez isso, faça. Depois adicione um usuário com uma certa senha para acessar este ftp. Aqui no tutorial vamos usar como usuário: “backup” e como senha: “segredo“. Utilize o seguinte script para automatizar o processo:
#!/bin/bash
#
DATA=`date +%Y_%m_%d`

# Dados do arquivo de backup
MAQUINA="sakura"
ARQUIVO="backup-full-$MAQUINA-$DATA.tar.gz"
DIRETORIOS="/etc /var/log"

# Dados do servidor FTP
HOST_FTP="192.168.0.1"
USUARIO_FTP="backup"
SENHA_FTP="segredo"

# A partir daqui não precisa mais editar.
# Cria o arquivo .tar.gz no /tmp (Temporário)
cd /tmp
tar zcf /tmp/$ARQUIVO $DIRETORIOS

# Acessa o FTP e coloca os arquivos
ftp -in <<EOF
   open $HOST_FTP
   user $USUARIO_FTP $SENHA_FTP
   bin
   lcd /tmp
   dele $ARQUIVO
   put $ARQUIVO
   bye
EOF

# Remove os arquivos temporarios
rm -rf /tmp/$ARQUIVO

Pronto! Lembre-se de proteger este arquivo aos olhos alheios, porque a senha do usuário do FTP está visível. Este pequeno script shell cria um backup dos diretórios “/etc” e “/var/log“, conecta ao servidor FTP e envia o arquivo. Você só precisará alterar as variáveis do começo do arquivo para as suas necessidades.

Com isso você terá o backup remoto que precisar. Modificando o script você pode criar também backups incrementais, e junto com o crontab, pode programar para as máquinas ficarem fazendo backups diários, semanais, mensais, ou como você quiser. Lembre-se sempre que os backups uma vez na máquina remota, devem ser colocados por segurança em uma mídia como fita DAT ou CD-ROM. Cabe à você decidir :) Bom proveito! Depois criarei mais dicas sobre o assunto.

Cópias remotas de arquivos

Fonte:http://www.devin.com.br/copias-remotas-de-arquivos/
Autor: Hugo Cisneiros (Eitch)
Uma das tarefas mais comuns de um administrador de sistemas é copiar arquivos de uma máquina para outra. Em rede, isto pode ser feito de diversas maneiras, como por exemplo: FTP, HTTP, SSH, RSYNC, entre outros. Este artigo mostra as principais formas de fazer isso. Vou tentar ser o mais direto possível.
Vamos usar aqui dois servidores exemplo:
  • servidor1.example.com (192.168.0.1)
  • servidor2.example.com (192.168.0.2)

SSH

O protocolo do SSH é seguro o suficiente para fazer cópias entre servidores em uma rede e é sempre o protocolo recomendado. Vamos agora para como fazer isso:
Copiando um arquivo simples de uma máquina para outra
servidor1$ scp maluco@servidor2.example.com:~/arquivo.txt ./

O comando acima copia o arquivo.txt do HOME (~) do usuário maluco, do servidor2 para o diretório atual do servidor1. Bem parecido com o comando cp.

Copiando todo um diretório de uma máquina para outra
servidor1$ scp -r maluco@servidor2.example.com:/home/maluco /tmp

Ou seja, copio o diretório maluco do servidor2 para a máquina atual, no diretório /tmp.
servidor1$ scp -Cpr maluco@servidor2.example.com:/home/maluco /tmp

O parâmetro -C agora faz a mesma ação anterior, só que agora compactando os dados antes de enviar pela rede. O ssh usa formato gzip e pode-se usar essa opção caso se queira economizar na banda de rede.

O parâmetro -p preserva todos modos e timestamps de arquivos, ideal para fazer uma cópia mais exata.

Usando o tar e o ssh para cópias mais exatas ainda

Por exemplo, um backup de sistema. O tar é ótimo para criar um arquivamento que preserva todas as permissões, usuários e grupos donos, modos, links simbólicos, etc. Desse jeito dá pra juntar os dois:
servidor1$ tar -cpzf - /etc | ssh maluco@servidor2.example.com "cat > /var/lib/backup/servidor1-etc.tar.gz"

O comando acima vai compactar o diretório /etc, só que ao invés de jogar o resultado em um arquivo, joga como STDIN, que o comando ssh pega e executa no servidor2 o comando cat, que por sua vez pega o STDIN e joga para o arquivo /var/lib/backup/servidor1-etc.tar.gz.

Em outras palavras, ele compacta o diretório /etc e já joga no outro servidor direto. Isso economiza tempo e espaço no servidor origem.
servidor1$ tar -C /home -cpzf - maluco | ssh maluco@servidor2.example.com "tar -C /home -xpzf -"

Agora ao invés de usar o cat, ele jogou diretamente o diretório na máquina remota, descompactado. É parecido com a opção -rp do scp, só que com a vantagem do tar: preserva modos, permissões, donos, links, etc.

Para mais informações sobre STDIN, STDOUT, pipes (|), tenho um outro artigo falando sobre isso.


HTTP e FTP


A primeira coisa que você precisa saber é que eu não vou ensinar a compartilhar os arquivos por HTTP e FTP neste artigo. É um assunto totalmente diferente, então vamos assumir que você já tenha os arquivos servidos via HTTP ou FTP em algum lugar :)

Pra quem já é um pouco acostumado com esses protocolos, um programa sempre vem na mente: wget. Mas além dele também há um comando muito útil para fazer operações mais complexas: o lftp.

Pegando arquivos e páginas via HTTP/FTP
servidor1$ wget -c 'http://servidor2.example.com/arquivo.txt' -O /home/maluco/informacoes.txt

O comando acima pega o arquivo.txt do servidor1 e o escreve (-O) em /home/maluco/informacoes.txt. Se você não especificar o -O, ele coloca no diretório atual com o mesmo nome remoto (no caso, arquivo.txt). O -c é para ele tente continuar um download caso o arquivo já exista, e a não ser que você queira sobrescrever os arquivos destino, é bom sempre usar a opção.
servidor1$ wget -c -r 'http://www.devin.com.br'

Já este vai fazer uma cópia recursiva de todo o site www.devin.com.br. Isso inclui os links e imagens, que o wget pega automaticamente do código HTML.

Mirrors com lftp

E falando em recursividade, o lftp fornece ótimos recursos para fazer este tipo de download. Por exemplo, eu estou afim de criar um espelho interno do repositório de pacotes do CentOS. Vamos supor que eu tenha escolhido o mirror kernel.org, via HTTP:
servidor1$ lftp
lftp :~> open http://mirrors.kernel.org/centos/5.5/os/x86_64/
lftp mirrors.kernel.org:/centos/5.5/os/x86_64> mirror -verbose
[...]

O lftp se encarrega de examinar o diretório e pegar todo o seu conteúdo: arquivos e sub-diretórios, salvando no diretório atual. A opção –verbose vai mostrando na tela o que o lftp está fazendo (analizando os diretórios, baixando os arquivos…).

O mesmo pode ser feito com um comando só, um ótimo jeito para se fazer isso automaticamente em shell-scripts:
servidor1$ lftp -c "open http://mirrors.kernel.org/centos/5.5/os/x86_64/ && mirror --verbose"

Ou seja, com o parâmetro -c, consigo executar os dois comandos (conectar, fazer mirror) de modo não-interativo, e depois ele sai do programa (para não sair, usa-se o -e ao invés de -c). O mirror também analisa e continua os downloads de onde parou, caso precise.

A mesma coisa pode ser feita via FTP, vamos supor agora que é preciso também de usuário e senha…
servidor1$ lftp -c "open ftp://usuario:senha@mirrors.kernel.org/centos/5.5/os/x86_64/ && mirror --verbose"

O lftp ainda suporta uma porrada de opções. São centenas. Nesse caso, a manpage sempre ajuda (man lftp). Uma das opções que eu acho muito legal é a exclude. Com a opção exclude, eu consigo fazer um download recursivo, retirando arquivos com nomes que não quero. Por exemplo:
servidor1$ lftp -c "set mirror:exclude-regex '(\.svn|SRPMS)' && open ftp://mirrors.kernel.org/centos/5.5/os/ && mirror --verbose"

No comando acima, eu estou excluindo qualquer arquivo ou diretório que tenha o contenha o nome .svn ou SRPMS. Isso me faz baixar apenas os diretórios i386 e x86_64. Fácil não? Aí é só usar a imaginação. Os exemplos aqui são muito comuns na hora de criar espelhos de repositórios e arquivos entre sistemas.

Mirror reverso (upload de arquivos)

No caso de mirror de um mirror reverso, ao invés de pegar os arquivos de um sistema remoto, eu coloco os arquivos no sistema remoto. A sintaxe é praticamente a mesma:
servidor1$ lftp -c "lcd /var/lib/backup && open ftp://usuario:senha@servidor2.example.com/backup/ && mirror -R --verbose"

O que mudou aqui: o comando lcd vai para o diretório local, onde os arquivos se encontram. Depois eu abro uma conexão FTP com servidor2.example.com, utilizando um usuário e senha. Em seguida eu faço um mirror reverso (opção -R), que ao invés de fazer download dos arquivos, vai fazer upload. Simples dessa forma.


RSYNC


O rsync foi feito especialmente para você sincronizar os arquivos de dois lugares e por isso ele é otimizado para isso. Geralmente é utilizado para copiar diretórios e seus conteúdos da forma mais exata possível (preservando permissões, modos, timestamps). Além disso, antes de começar a copiar, ele analisa o destino (ou origem, dependendo do caso) e vê o que realmente tem que ser copiado. Se um arquivo já existe no destino, para que copiar de novo?

O rsync pode funcionar via protocolo próprio, ou via ssh. Se existe um servidor rsync, pode-se usar ele. Para criar um, vai um pouco fora do escopo deste artigo, mas não é tão complicado também. Na maioria das vezes, você vai querer usar o rsync via ssh, que é o caso mais comum.

Sincronizando um diretório no servidor remoto
servidor1$ rsync -e "ssh" -avr /var/lib/backup/ maluco@servidor2.example.com:/var/lib/backup/

No comando acima, utilizei o ssh (-e “ssh”) para fazer o transporte. As opções -avr copiam recursivamente (-r), mostrando tudo o que for sendo copiado (-v) e da forma mais exata possível, preservando (-a). Até aí tudo bem…

… Mas preste bastante atenção! O rsync é muito sensível com a barra no final da origem e destino. Então coloque isso na cabeça:


  • Quando não se usa a barra no final, o rsync copia o diretório e todo seu conteúdo;
  • Quando usar a barra no final, o rsync copia apenas o conteúdo do diretório.

Confuso? Eu também fiquei. No exemplo anterior, eu copiei o conteúdo do diretório backup (localizado em /var/lib) para o /var/lib/backup do servidor2. Isso significa que o diretório /var/lib/backup deve existir no servidor2, senão é capaz de dar erro. Ficou assim:
servidor2$ ls /var/lib/backup
1   11  13  15  17  19  20  22  24  26  28  3   31  33  35  37  39  40  42  44  46  48  5   6  8
10  12  14  16  18  2   21  23  25  27  29  30  32  34  36  38  4   41  43  45  47  49  50  7  9

E se eu tirar uma barra?
servidor1$ rsync -e "ssh" -avr /var/lib/backup maluco@servidor2.example.com:/var/lib/backup/

Nesse caso, olha só como ia ficar:
servidor2$ ls /var/lib/backup
backup
servidor2$ ls /var/lib/backup/backup
1   11  13  15  17  19  20  22  24  26  28  3   31  33  35  37  39  40  42  44  46  48  5   6  8
10  12  14  16  18  2   21  23  25  27  29  30  32  34  36  38  4   41  43  45  47  49  50  7  9

Como tirei a barra, ele também copiou o diretório backup, ao invés de apenas seu conteúdo. Então lembre-se sempre… Com barra: só conteúdo; Sem barra: diretório e conteúdo.

Assim como lftp, o rsync também aceita excluir arquivos por nome:
servidor1$ rsync -e "ssh" --exclude='.svn' -avr /var/www/html/aplicacao maluco@servidor2.example.com:/var/www/html

No comando acima, sincronizamos o diretório /var/www/html/aplicacao, mas excluindo qualquer operação com arquivos que tem no nome “.svn“. Uma prática muito comum por aí.

Por padrão, o rsync não remove arquivos e diretórios do destino. Isso significa que a sincronização é apenas em uma mão. Se no servidor1 novos arquivos surgirem, ou arquivos forem modificados, o rsync vai sincronizar. Mas se um arquivo ou diretório for removido, ele não será removido no servidor2. Para resolver isso, usa-se a opção –delete:
servidor1$ rsync -e "ssh" --exclude='.svn' --delete -avr /var/www/html/aplicacao maluco@servidor2.example.com:/var/www/html

Dessa forma você evita de ficar acumulando “lixo” no servidor2.

Há no entanto um problema com este método. O problema é que os dados, enquanto armazenados não estão em criptografados. Se alguém entra e rouba o server, vão ter acesso aos dados. Depois, se alguém rouba o server de backup, não há procedimentos de backup offsite, para guardar o backup fora da empresa. Também dessa forma não há checagem de integridade de dados. Quando se usa um cp para copiar os dados, eles podem chegar do outro lado com defeito e não será feita nenhuma checagem disso (md5checksum) caso a mídia apresente algum defeito, um badblock, etc. O melhor mesmo é usar um sistema de backup, como o Nimbus Opensource Backup, GPL e prevê todas as boas práticas em backup. Está disponível em http://www.trynimbus.com grátis (GPL).

terça-feira, 29 de junho de 2010

Agendando tarefas com o cron

Autor:Carlos E. Morimoto
Fonte:http://www.guiadohardware.net/dicas/cron.html
O agendamento de tarefas é um recurso essencial em servidores. No Linux, o daemon responsável pela tarefa é o cron. Ele é o responsável por diversas funções executadas automaticamente na maioria das distribuições, tais como o rotacionamento dos logs e pode ser programado para executar operações diversas, tais como scripts de backup.
O arquivo principal de configuração é o "/etc/crontab" e o script responsável pelo serviço é o "/etc/init.d/cron" (ou "/etc/init.d/crond" no Fedora e no CentOS). A configuração do cron pode parecer indigesta à primeira vista, mas na verdade ela é bastante lógica e, dependendo do ponto de vista, até mesmo simples.
Você pode criar um agendamento simples adicionando a linha abaixo no final do arquivo:
* * * * * root date >> /tmp/testedata
Ela faz com que o sistema execute o comando "date >> /tmp/testedata" uma vez a cada minuto. O comando "date" mostra o horário atual do sistema e as duas setas direcionam a saída do comando para o arquivo especificado.
Depois de salvar o arquivo, você precisa apenas esperar um minuto ou dois e verificar o conteúdo do arquivo para checar se o agendamento está funcionando. Ele conterá várias linhas com a saída do comando, como em:
Qui Jun 19 04:36:38 BRT 2008
Qui Jun 19 04:36:39 BRT 2008
O cron checa o conteúdo do arquivo uma vez a cada minuto, de forma que não é necessário reiniciar o serviço para que a alteração entre em vigor. Para desativar o agendamento, basta remover ou comentar a linha.
Os cinco campos separados por espaço no início da linha permitem definir o horário ou a periodicidade em que uma determinada tarefa será executada. O primeiro campo especifica os minutos, o segundo especifica as horas, o terceiro especifica o dia, o quarto o mês e o quinto especifica o dia da semana. A princípio essa designação parece muito confusa, mas na verdade ela é bastante prática.
Para que o comando fosse executado todos os dias às 6:20 da manhã, usaríamos:
20 06 * * * root date >> /tmp/testedata
Os dois campos especificam a hora, como você pode ver. Os outros três (dia, mês e dia da semana) permanecem com o asterisco, o que faz com que o comando seja executado todos os dias. Se a idéia fosse fazer com que ele fosse executado nessa mesma hora, mas apenas aos domingos (imagine o caso de um script de backup que precisasse desativar temporariamente o banco de dados, deixando o servidor fora do ar, por exemplo), você usaria:
20 06 * * 0 root /usr/local/bin/script-de-backup
Veja que agora usamos o número 0 no último campo, que indica o dia da semana. Na sintaxe do cron, os dias da semana são numerados de 0 a 6, onde o "0" representa o domingo e o "6" o sábado.
É possível também especificar mais de um valor em um mesmo campo, fazendo com que o script seja executado duas vezes por dia, ou duas vezes por semana, sem precisar incluir duas linhas diferentes. Se deseja que um script seja executado tanto aos domingos quanto às quartas-feiras, sempre às 4:00 da manhã, você usaria:
00 04 * * 0,3 root /usr/local/bin/script-de-backup
A vírgula no campo do dia da semana permite especificar mais de um valor, ela é interpretada pelo cron como um "e", de forma que "0,3" é lido como "aos domingos e às quartas feiras".
É possível também usar a "/" para indicar um período. Para fazer com que o script seja executado a cada 5 minutos, você usaria:
*/5 * * * * root /usr/local/bin/verificar-servidor
O mesmo pode ser feito para os demais campos. Para que o script fosse executado a cada 3 horas (1:15, 4:15, 7:15, etc.), por exemplo, você usaria:
15 */3 * * * root /usr/local/bin/verificar-servidor
Continuando, temos os campos com o dia e o mês. Para executar um script às 6:20 da manhã, no primeiro dia de cada mês, você usaria:
00 06 1 * * root /usr/local/bin/gerar-folha-de-pagamento
Para executar apenas no dia primeiro de janeiro, uma vez por ano, usaria:
00 06 1 * * root /usr/local/bin/feliz-ano-novo
O cron executa a tarefa apenas se todas as condições especificados nos campos sejam satisfeitas. Isso permite especificar condições bastante específicas. Para executar um comando às 00:15 toda vez que uma sexta feira cair no dia 13 (imagine que você seja supersticioso e queira fazer um backup extra, por exemplo :), você usaria:
15 00 13 * 5 root /usr/local/bin/backup-extra
Naturalmente, você pode também fazer com que os scripts sejam executados usando outros logins de usuário em vez do root, o que é o ideal do ponto de vista da segurança. Para isso, basta substituir o "root" pelo login desejado. Com isso, o script é executado dentro das permissões do usuário, o que limita qualquer possível dano ou brecha de segurança que possa ser aberta pelo script.
Em quase todas as distribuições atuais, o arquivo "/etc/crontab" vem pré-configurado para que o sistema execute os scripts incluídos nas pastas "/etc/cron.hourly", "/etc/cron.daily", "/etc/cron.weekly" e "/etc/cron.monthly", executados, respectivamente, uma vez a cada hora, dia, semana e mês:
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
Esta configuração facilita o agendamento de tarefas, já que para fazer com que um script seja executado todos os dias, por exemplo, você precisa apenas colocá-lo dentro da pasta "/etc/cron.daily". Olhando o conteúdo da pasta, você notará a presença de diversos scripts de manutenção do sistema, como o logrotate, encarregado de rotacionar e compactar os arquivos de log, evitando que eles cresçam indefinidamente.
Os scripts incluídos na programação do cron são arquivos de texto simples, contendo os comandos que você deseja que sejam executados. Aqui temos um exemplo de script simples de backup, que usa o rsync para salvar uma cópia do conteúdo da partição "/var/www" na pasta "/mnt/sdb1", que corresponderia a um HD separado, salvando a saída do comando, em um arquivo de texto, que você pode examinar posteriormente em busca de erros:
#! /bin/sh
/usr/bin/rsync -av --delete /var/www/ /mnt/sdb1 >> /var/log/backup-www.log
Para que o script fosse executado todos os dias, você precisaria apenas copiá-lo para a pasta "/etc/cron.daily" e marcar a permissão de execução (chmod +x). Outra opção seria simplesmente adicionar uma nova linha no arquivo "/etc/crontab", especificando a hora em que você deseja que ele seja executado.

segunda-feira, 28 de junho de 2010

Escrevendo scripts de Backup (2008)

Autor:Carlos E. Morimoto
Fonte:http://www.guiadohardware.net/tutoriais/backup/
http://www.guiadohardware.net/tutoriais/backup2/
 Os backups são uma parte importante da administração de qualquer servidor. Diferente de um desktop, onde você pode simplesmente fazer uma imagem do HD usando o partimage ou outro programa similar, em uma servidor os backups precisam, quase sempre, serem feitos com o servidor em operação, sem atrapalharem o acesso dos usuários. O nível de dificuldade também é um pouco maior, já que além de arquivos e pastas, é necessário salvar também arquivos de configuração, bases de dados do MySQL e assim por diante.
Por mais confiável que seja a máquina, desastres acontecem, sem falar na possibilidade de erro humano. Sem backups regulares, é apenas questão de tempo até que você tenha problemas e perca dados importantes.
Em resumo, as principais pastas com as quais você precisa se preocupar ao fazer backup do servidor são:
/var/www: Em um servidor web, a pasta com as páginas é sempre o diretório mais importante, já que é nele que ficarão a maior parte dos arquivos dos usuários.
/var/lib/mysql: Este é o diretório padrão das bases de dados do MySQL, que em muitos casos são tão ou mais importantes que as pastas dos sites propriamente ditos. Embora seja associado ao uso em servidores web, o MySQL pode ser usado para os mais diversos tipos de tarefas.
/home: Se você configurou os virtual hosts do Apache para utilizarem pastas dentro dos diretórios home dos usuários, a pasta home assume o posto de diretório essencial, no lugar da pasta /var/www. O home também é importante caso seja usado para armazenar o spool de e-mails, no caso de servidores de arquivos ou em servidores de acesso remoto (como no caso do LTSP).
/etc: É importante que você faça também backup das configurações do servidor, concentradas na pasta "/etc", caso contrário, você vai passar maus bocados tentando se lembrar das configurações, contas de usuários e outras informações ao reconfigurar o servidor após algum desastre. :)
/var/log: Os logs do sistema também são importantes. Em muitos casos existem normas administrativas ou até mesmo normas legais que tornam obrigatório manter os logs de acesso por longos períodos, daí a necessidade de incluí-los no backup.
Além dos diretórios de dados do sistema, é importante que você tome nota de todas as partições montadas em diretórios fora das pastas principais do sistema que sejam usadas para armazenar arquivos, além de outras pastas que você utilize para guardar dados ou configurações.
Depois de definidos os diretórios a incluir no backup, falta definir que tipo de mídia utilizar.
Antigamente, as unidades de fita eram as mais utilizadas para backup de grandes volumes de dados. As principais vantagens das unidades de fita eram a grande capacidade, combinada com a boa confiabilidade e um custo por megabyte relativamente baixo. Temos aqui uma IBM 7329 SLR100, uma unidade SCSI antiga, que utiliza fitas de 50 GB, com um carregador automático com capacidade para 8 fitas, totalizando 400 GB. O "100" no nome indica a capacidade estimada levando em conta um fator de compressão de 2:1, que dependia dos tipos de arquivos incluídos no backup e que, naturalmente, nem sempre era atingido:
clip_image001
Utilitários como o tar foram originalmente desenvolvidos para facilitarem os backups em fita, gerando um único arquivo contendo todos os dados, que era então gravado na fita de forma sequencial. Para salvar um backup da pasta "/var/www" em uma unidade de fita detectada pelo sistema como "/dev/st0", apenas empacotando os arquivos (sem comprimir), você usaria o comando:
# tar -cvf /dev/st0 /var/www
Isso seria prático enquanto você pudesse armazenar os backups diários em uma única fita, ou caso você utilizasse uma unidade com um carregador automático. É possível dividir o backup em vários volumes e salvá-lo em fitas separadas, mas isso torna o processo extremamente imprático, sem falar que os custos se multiplicam junto com o número de fitas necessárias.
Hoje em dia, existem unidades de fita com mídias de até 800 GB reais (ou 1.6 TB comprimidos), como a Tandberg LTO-4 FH (que custa, em julho de 2008, nada menos do que US$ 4500, mais o custo das fitas), entretanto, elas são bastante caras, o que torna os HDs uma opção muito mais atrativa, já que já existem no mercado HDs de 1 TB a preços competitivos.
Surge então a figura do NAS, um servidor de arquivos dedicado, que freqüentemente utiliza vários HDs em RAID de forma a obter a capacidade necessária. Além das inúmeras opções de produtos comerciais, você pode montar seu próprio NAS usando um PC com Linux. Ao utilizar um NAS, ou outro tipo de servidor de armazenamento, os backups tornam-se mais simples, pois podem ser feitos via rede. Com isso, todo o trabalho manual de trocar as fitas de armazenamento, ou plugar e desplugar HDs externos é eliminado e os backups podem se tornar um processo inteiramente automatizado.
Existem também os casos em que o volume de dados a armazenar é pequeno, o que torna viável utilizar DVDs ou mesmo CD-ROMs para realizar os backups. A vantagem nesse caso é que as mídias são baratas e você pode simplesmente queimar uma nova mídia a cada backup, armazenando todas as cópias antigas. Os CDs e DVDs possuem também uma boa longevidade; mídias de boa qualidade, armazenadas em um ambiente sem luz e com baixa umidade duram cerca de 20 anos ou, em muitos casos, até mais.
Durante a década de 70, vários utilitários foram desenvolvidos para fazer backup de arquivos armazenados em servidores Linux. Os computadores da época eram muito limitados, por isso os utilitários precisavam ser simples e eficientes, e deveriam existir meios de agendar os backups para horários de pouco uso das máquinas.
Sugiram então utilitários como o tar e o gzip e, mais tarde, ferramentas como o rsync. Estes utilitários eram tão eficientes que continuaram sendo usados ao longo do tempo e, por incrível que possa parecer, são usados sem grandes modificações até os dias hoje.
Naturalmente, existem muitos utilitários amigáveis de backup, como o Amanda (http://sourceforge.net/projects/amanda/), mas, internamente, eles continuam utilizando como base o o dump, tar, gzip e outros trigenários. Mais incrível ainda é que estes utilitários possuem uma base de usuários relativamente pequena. A maior parte dos backups ainda é feita através de scripts personalizados, escritos pelo próprio administrador. E, novamente, estes scripts utilizam o tar, gzip, rsync e outros. Vamos começar com alguns exemplos simples:
Para compactar o conteúdo de uma pasta, usamos o tar combinado com o gzip ou o bzip2. O tar agrupa os arquivos e o gzip/bzip2 os compacta. Os arquivos compactados com o gzip usam por padrão a extensão "tar.gz", enquanto os compactados com o bzip2 usam a extensão "tar.bz2". O bzip2 é mais eficiente (chega a obter 10% ou mais de compressão adicional) mas em compensação é bem mais pesado: demora cerca de 3 vezes mais para compactar os mesmos arquivos. Você escolhe entre um e outro de acordo com a tarefa.
O comando para compactar uma pasta é similar ao "tar -zxvf" que usamos para descompactar arquivos. Para compactar a pasta "arquivos/", criando o arquivo "arquivos.tar.gz", o comando seria:
$ tar -zcvf arquivos.tar.gz arquivos/
O "c" indica que o tar deve criar um novo arquivo e o "v" faz com que exiba informações na tela enquanto trabalha. Se preferir comprimir em bz2, muda apenas a primeira letra; ao invés de "z" usamos "j":
$ tar -jcvf arquivos.tar.bz2 arquivos/
Para descompactar o arquivo posteriormente, trocamos a opção "c" por "x", como em:
$ tar -jxvf arquivos.tar.bz2
Como não indicamos uma pasta de destino, o arquivo será simplesmente descompactado na pasta atual. Se o arquivo não é muito grande ou se o espaço em disco não é problema, você pode simplesmente descompactar o arquivo dentro da sua pasta home, ou em outro diretório com espaço suficiente disponível e copiar manualmente os arquivos desejados para a pasta de destino. Essa acaba sendo a opção mais segura, já que você tem mais tempo para revisar tudo e ter certeza de que não está substituindo arquivos por versões antigas.
Você pode também descompactar o arquivo diretamente na pasta desejada. Imagine que você fez anteriormente o backup da pasta "/var/www/site", gerando o arquivo "site.tar.gz", usando os comandos:
# cd /var/www
# tar -zcvf /mnt/sdb1/backups/site.tar.gz site
Nesse caso, o arquivo contém a pasta "site/" e todo o seu conteúdo. Para restaurá-lo posteriormente, diretamente no destino, você usaria:
# cd /var/www
# tar -zxvf /mnt/sdb1/backups/site.tar.gz
Como o comando é executado diretamente dentro da pasta "/var/www/", os arquivos são restaurados diretamente na pasta "site". Usado desta forma, o tar subscreve os arquivos da pasta de destino sem pedir confirmação, por isso tenha cautela ao usá-lo. É muito fácil errar o diretório e restaurar os arquivos na pasta errada, ou especificar o arquivo incorreto e subscrever o conteúdo da pasta pelo de um backup antigo.
Continuando, um dos grandes problemas em utilizar arquivos compactados é que é muito difícil recuperar o conteúdo do arquivo caso ele seja corrompido por qualquer motivo (um badblock no HD, ou um erro durante a transferência, por exemplo). Diferente de em uma pasta com diversos arquivos, onde um ou mais badblocks apenas fariam com que alguns dos arquivos ficassem danificados, erros em um arquivo compactado podem comprometer todo o seu conteúdo.
Tendo isso em mente, é saudável verificar os backups depois de copiá-los para a mídia de destino, o que pode ser feito usando o próprio tar. Nesse caso, usamos a opção "-tf", que faz com que ele liste o conteúdo do arquivo, como em:
$ tar -tf arquivos.tar.bz2
Isso obrigará o tar a abrir o arquivo e listar seu conteúdo. Se houver qualquer erro durante o processo, ele exibirá uma mensagem de erro, alertando sobre o problema.
Estes comandos seriam ideais para fazer um backup completo de uma ou várias pastas do sistema, gerando um arquivo compactado que poderia ser armazenado num HD externo, gravado em um DVD ou mesmo transferido via rede para outro servidor.
Imagine agora um outro cenário, onde você precisa fazer backup dos arquivos de uma pasta de trabalho diariamente. Os arquivos gerados não são muito grandes e você tem muito espaço disponível, mas é necessário que os backups diários sejam feitos em arquivos separados e sejam guardados por um certo período, de forma que seja possível recuperar um arquivo qualquer a partir do backup feito em uma determinada data.
Ao invés de ficar renomeando os arquivos, você poderia usar um pequeno script para que os arquivos fossem gerados já com a data e hora incluída no nome do arquivo:
DATA=`date +%Y-%m-%d-%H.%M`
cd /mnt/backup
tar -zcvf trabalho-"$DATA".tar.gz /mnt/hda6/trabalho/
A primeira linha do script cria uma variável "DATA", contendo o resultado do comando "date +%Y-%m-%d-%H.%M.%S" (os caracteres "`" usados no comando são crases). O comando date retorna a data e hora atual, como em "Qua Jul 2 10:23:46 BRT 2008". A saída padrão não é muito adequada para usar em nomes de arquivos, por isso usamos as opções para alterar o formato de saída, de modo que o resultado seja "2008-07-02-10.23" (ano, mês, dia, hora, minuto). Usamos este valor no nome do arquivo com o backup, de forma que, cada vez que você chame o script, seja gerado um arquivo com a data e hora em que foi gerado.
O próximo passo é fazer com que este script de backup seja executado diariamente, de forma automática, o que pode ser feito usando o cron, que apresentei na dica anterior: http://www.guiadohardware.net/dicas/cron.html
Em primeiro lugar, salve os comandos em um arquivo de texto, que vamos chamar de "script-backup" e transforme-o em executável:
# chmod +x script-backup
Para que o script seja executado automaticamente todos os dias, edite o arquivo "/etc/crontab" adicionando uma nova linha, especificando o horário em que o script será executado, o login sob o qual ele será executado (para simplificar as coisas, você pode utilizar o próprio root) e a localização do script, como em:
25 6 * * * root /usr/local/bin/script-backup
O "25 6" indica o minuto e a hora. Se quiser que o script seja executado às 11 da noite, por exemplo, mude para "00 23". As alterações feitas no arquivo são lidas automaticamente pelo cron, de forma que não é necessário reiniciar o serviço. Se quiser verificar se o cron está mesmo ativo, use o comando "ps aux | grep cron", que deverá retornar algo similar a: "root 2002 0.0 0.1 2280 848 ? Ss Jun30 0:00 /usr/sbin/cron".
Nesse primeiro exemplo, usei a pasta "/mnt/backup" para salvar os arquivos. Esta pasta pode ser o ponto de montagem de um HD externo ou de um compartilhamento de rede, por exemplo. O seu script pode conter os comandos necessários para montar e desmontar a partição automaticamente, além de executar operações diversas definidas por você.
Imagine, por exemplo, que o backup é sempre feito na primeira partição de um HD externo, ligado na porta USB, que é sempre detectada pelo sistema como "/dev/sda1". O script deve ser capaz de montar a partição, gravar o arquivo de backup e depois desmontá-la. Se, por acaso, o HD não estiver plugado, o script deve abortar o procedimento.
Para isso, precisamos verificar se o HD realmente foi montado depois de executar o comando "mount /dev/sda1 /mnt/sda1". Existem muitas formas de fazer isso, uma das mais simples é filtrar a saída do comando "mount" (que mostra todos os dispositivos montados) usando o grep para ver se o "/mnt/sda1" aparece na lista. Se não estiver, o script termina, caso esteja, ele continua, executando os comandos de backup:
mount /dev/sda1 /mnt/backup
montado=`mount | grep /mnt/backup`
if [ -z "$montado" ]; then
exit 2
else
DATA=`date +%Y-%m-%d-%H.%M`
cd /mnt/backup
tar -zcvf trabalho-"$DATA".tar.gz /mnt/hda6/trabalho/
umount /mnt/sda1
fi
Uma vez que o cron fosse configurado para executar o script diariamente, o backup passaria a ser feito automaticamente sempre que você deixasse o HD externo plugado no final do expediente. Se esquecer de plugar o HD em algum dia, o script percebe que a partição não foi montada e não faz nada.
Se preferir que o script grave o backup em um DVD, ao invés de simplesmente salvar em uma pasta, você pode usar o "growisofs" para gravá-lo na mídia. Neste caso, vamos gerar o arquivo em uma pasta temporária e deletá-lo depois da gravação:
DATA=`date +%Y-%m-%d-%H.%M`
# Sanity-check para ter certeza de que tudo está em ordem:
rm -rf /tmp/backup; mkdir /tmp/backup; cd /tmp/backup
# Gera o arquivo, grava o DVD e deleta a pasta temporária
tar -zcvf trabalho-"$DATA".tar.gz /mnt/hda6/trabalho/
growisofs -speed=2 -Z /dev/dvd -R -J /tmp/backup/trabalho-"$DATA".tar.gz
cd ../; rm -rf /tmp/backup
O "-speed=2" permite que você especifique a velocidade de gravação do DVD, enquanto o "-Z" cria uma nova seção dentro da mídia. É possível usar o mesmo disco para gravar vários backups (se o espaço permitir) adicionando a opção "-M" (logo depois do "-Z", dentro do comando) a partir da segunda gravação, que adiciona novas seções no DVD, até que o espaço se acabe.
O "/dev/dvd" indica o dispositivo do drive de DVD. A maioria das distribuições cria o link /dev/dvd apontando para o dispositivo correto, mas, em caso de problemas, você pode indicar diretamente o dispositivo correto, como, por exemplo, "/dev/hdc". As opções "-R -J" adicionam suporte às extensões RockRidge e Joilet, que oferecem (respectivamente) suporte a nomes de arquivos com mais de 8 caracteres no Linux e no Windows.
Se o cron for configurado para executar o script todos os dias, você só precisará se preocupar em deixar o DVD no drive antes de sair. Se quiser que ele faça graça, ejetando a mídia depois de terminar a gravação, adicione um "eject /dev/dvd" no final do script.
Se preferir fazer os backups em CDR, crie uma imagem ISO usando o mkisofs e em seguida grave-a no CD usando o cdrecord. Nesse caso, o comando do growisofs dentro do script seria substituído por:
mkisofs -r -J -o trabalho.iso /tmp/backup/trabalho-"$DATA".tar.gz
cdrecord dev=/dev/hdc trabalho.iso
Este comando do cdrecord funciona em distribuições recentes, que utilizam o Kernel 2.6 em diante (com o módulo ide-cd). No Kernel 2.4, era usada emulação SCSI para acessar o gravador de CD, fazendo com que ele fosse visto e acessado pelo sistema como se fosse um gravador SCSI. Nesse caso, o comando de gravação seria "cdrecord dev=0,0,0 -data arquivo.iso", onde o "0,0,0" é o dispositivo do gravador, que você descobriria usando o comando "cdrecord -scanbus".
Outra pequena observação é que nas distribuições derivadas do Debian o cdrecord é substituído pelo wodim, um fork do projeto que desempenha a mesma função. Nelas, você recebe um "bash: cdrecord: command not found" ao executar o comando, já que o nome do arquivo é diferente. Você pode resolver o problema de forma simples criando um link:
# ln -s /usr/bin/wodim /usr/bin/cdrecord
Outra boa opção seria salvar os backups em um servidor externo, de preferência um servidor remoto, situado em outro estado ou em outro país. Usar dois servidores em locais diferentes elimina a possibilidade de algum tipo de desastre (como um incêndio ou uma inundação) destruir tanto o servidor quanto os backups.
Uma forma simples de fazer com que o script consiga transferir os arquivos automaticamente no final do processo é utilizar um par de chaves do SSH sem passphrase, o que permite que o script transfira arquivos usando o comando "scp", sem precisar lhe pedir a senha ou a passphrase de acesso ao realizar cada cópia. Essa opção é um pouco menos segura do que usar chaves protegidas por uma passphrase, já que caso alguém consiga obter acesso ao arquivo ".ssh/id_rsa" dentro no home do usuário, poderá obter acesso ao servidor. Entretanto, em muitas situações este é um risco aceitável, principalmente se o backup é feito diretamente entre dois servidores protegidos. Além do mais, o risco é reduzido caso você utilize uma conta limitada no segundo servidor.
O primeiro passo seria criar um usuário no segundo servidor, que será usado para permitir o acesso do script. Aproveite para já ajustar o diretório home, especificando a pasta que será usada para armazenar os backups, como em:
# adduser --home /mnt/sdb1/backups bkuser
Em seguida, criamos o par de chaves que será usado para o acesso no primeiro servidor usando o comando "ssh-keygen -t rsa". Ele deve ser executado usando o usuário que será usado para executar o script de backup. Se ele for ser executado pelo root, então o comando é também executado como root:
# ssh-keygen -t rsa
Como a idéia é criar uma chave que possa ser usada para login automático, simplesmente pressione Enter quando o ssh-keygen perguntar pela passphrase, deixando-a em branco.
O próximo passo é instalar a chave gerada no segundo servidor (o "backup.gdhn.com.br" no exemplo), usando o comando "ssh-copy-id", especificando o usuário criado no passo anterior e o endereço do segundo servidor, como em:
# ssh-copy-id -i ~/.ssh/id_rsa.pub bkuser@backup.gdhn.com.br
Com isso, o primeiro servidor passa a ter acesso direto ao segundo através do usuário "bkuser" (especificado no comando), que usaremos para transferir os arquivos através do scp. Você pode fazer um teste transferindo um arquivo qualquer do primeiro servidor para o segundo, como em:
# scp arquivo.tar.gz bkuser@backup.gdhn.com.br:/mnt/sdb1/backups/
Você perceberá que o comando será executado diretamente, sem pedir senha. O próximo passo é adicionar o comando para transferir o arquivo no seu script de backup, como neste exemplo:
#!/bin/sh
DATA=`date +%Y-%m-%d-%H.%M`
cd /mnt/backup
tar -zcvf www-$DATA.tar.gz /var/www
scp www-$DATA.tar.gz bkuser@backup.gdhn.com.br:/mnt/sdb1/backups/
rm -f www-$DATA.tar.gz
Com isso, o script gera o arquivo com o backup, copia para o segundo servidor via scp e, depois de concluída a transferência, deleta a cópia local do arquivo, de forma que elas não se acumulem até acabar com o espaço em disco.
O passo final seria automatizar a execução do script, adicionando uma entrada no arquivo "/etc/crontab" (do primeiro servidor), como em:
59 4 * * * root /usr/local/bin/script-backup
Esta entrada faria com que o script fosse executado todos os dias às 4:59 da manhã, sempre gerando um novo arquivo com a data de quando foi executado e copiando-o para o segundo servidor, onde os backups ficarão arquivados.

Outro grande aliado na hora de programar backups é orsync. Ele permite sincronizar o conteúdo de duas pastas, transferindo apenas as modificações. Ele não trabalha apenas comparando arquivo por arquivo, mas também comparando o conteúdo de cada um. Se apenas uma pequena parte do arquivo foi alterada, o rsync transferirá apenas ela, sem copiar novamente todo o arquivo.

Ele é uma forma simples de fazer backups incrementais de grandes quantidades de arquivos, ou mesmo partições inteiras, mantendo uma única cópia atualizada de tudo em um HD externo ou num servidor remoto. Este backup incremental pode ser atualizado todo dia e complementado por um backup completo (para o caso de um desastre acontecer), feito uma vez por semana ou uma vez por mês.
Para instalar o rsync, procure pelo pacote "rsync" no gerenciador de pacotes. No Debian instale com um "apt-get install rsync" e no Mandriva com um "urpmi rsync".
Para fazer um backup local, basta informar a pasta de origem e a pasta de destino, para onde os arquivos serão copiados, como em:
$ rsync -av /mnt/hda6/trabalho/ /mnt/backup/
A opção "-a" (archive) faz com que todas as permissões e atributos dos arquivos sejam mantidos, da mesma forma que ao criar os arquivos com o tar, e o "v" (verbose) mostra o progresso na tela.
A cópia inicial vai demorar um pouco, mais do que demoraria uma cópia simples dos arquivos, mas, a partir da segunda vez, a operação será muito mais rápida, já que serão copiadas apenas as mudanças.
Note que neste comando estamos copiando a pasta "trabalho" recursivamente para dentro da "/mnt/backup", de forma que seja criada a pasta "/mnt/backup/trabalho". Se omitíssemos a barra, como em "rsync -av /mnt/hda6/trabalho /mnt/backup/", o rsync copiaria o conteúdo interno da pasta diretamente para dentro da "/mnt/backup". Como pode ver, a barra final é importante dentro da sintaxe do rsync.
Se algum desastre acontecer e você precisar recuperar os dados, basta inverter a ordem das pastas no comando, fazendo com que a pasta com o backup seja a origem e a pasta original seja o destino, como em:
$ rsync -av /mnt/backup/trabalho/ /mnt/hda6/trabalho
O rsync é bastante prático para automatizar backups locais, como em casos em que o servidor possui dois HDs e você deseja que o segundo armazene uma cópia completa dos arquivos do primeiro, para o caso de qualquer eventualidade. Um exemplo de script de backup simples para esta função seria:
#! /bin/sh
mount /dev/sdb1 /mnt/sdb1
rsync -av --delete /var/ /mnt/sdb1/ >> /tmp/rsync.log
rsync -av --delete /home/ /mnt/sdb1/ >> /tmp/rsync.log
rsync -av --delete /etc/ /mnt/sdb1/ >> /tmp/rsync.log
umount /mnt/sdb1
hdparm -S 24 /dev/sdb
Neste exemplo, estou salvando cópias das pastas "var", "home" e "etc" na partição "/dev/sdb1", montada pelo script dentro da pasta "/mnt/sdb1". O ">> /tmp/rsync.log" faz com que a saída dos comandos seja salva no arquivo especificado, de forma que você possa verificar as mensagens no dia seguinte, em busca de erros.
O "--delete" faz com que arquivos apagados na pasta original sejam apagados também na pasta do backup, fazendo com que ela se mantenha como uma cópia fiel. Naturalmente, a opção pode ser removida do comando se o objetivo é fazer com que o backup mantenha arquivos antigos, de forma que você possa recuperá-los posteriormente, caso necessário.
Uma peculiaridade do script é que a partição é montada no início do script e desmontada no final. A idéia seria que o segundo HD fosse usado apenas para o backup e ficasse desativado no restante do tempo, de forma que o desgaste (e a possibilidade de qualquer defeito mecânico) seja reduzido. O comando "hdparm -S 24 /dev/sdb" executado no final do script ajusta o gerenciamento de energia para o HD, fazendo com que ele entre em modo standby (onde os discos param de girar, as cabeças de leitura ficam estacionadas e apenas parte dos componentes da placa lógica ficam ativos) depois de 2 minutos de inatividade. Com isso, o HD será ativado no início da backup e ficará dormindo todo o resto do tempo, praticamente sem consumir energia.
Este script poderia ser executado uma vez por dia usando o cron, de forma que você tivesse sempre um backup do dia anterior à mão, pronto para recuperar qualquer arquivo deletado acidentalmente. Naturalmente, este backup local deveria ser complementado por algum backup remoto, que permitisse recuperar os arquivos em casos de catástrofes. Para isso, você poderia complementá-lo com um backup completo feito usando o tar e o scp, como vimos no tópico anterior.
É possível também fazer backups incrementais com o rsync de forma muito simples usando-o em combinação com o comando "cp -al". O comando "cp -a" permite fazer uma cópia exata de uma pasta, copiando todo o seu conteúdo e mantendo todas as permissões de acesso. Entretanto, quando adicionamos o parâmetro "l", o cp passa a se comportar de forma completamente diferente, criando hard links em vez de copiar os arquivos.
Diferente dos soft links (criados usando o comando "ln -s"), os hard links são atalhos que apontam diretamente para os inodes dos arquivos de destino dentro do sistema de arquivos. Com isso, eles são vistos pelo sistema exatamente da mesma forma que os arquivos reais, com exceção de que eles não ocupam espaço (com exceção dos poucos bytes usados pelo atalho). Ao usar o comando "cp -al", criamos uma cópia exata da pasta original, onde os arquivos são substituídos por hard links apontando para os arquivos originais.
Com isso, podemos usar o rsync para realizar backups incrementais, usando o "cp -al" para gerar "snapshots" das cópias dos dias anteriores. Veja um exemplo:
rm -rf backup.6
mv backup.5 backup.6
mv backup.4 backup.5
mv backup.3 backup.4
mv backup.2 backup.3
mv backup.1 backup.2
cp -al backup.0 backup.1
rsync -av --delete /arquivos/ backup.0
Se executado diariamente, este pequeno script criaria um conjunto de 7 pastas, numeradas de 0 a 6, usadas para armazenar os backups. Tudo começaria com a pasta "backup.0", que armazenaria sempre o backup completo, feito através do rsync. Cada vez que o script é executado, o sistema rotaciona todas as pastas anteriores, copia a pasta "backup.0" para a "backup.1" usando o "cp -al" e em seguida atualiza o backup completo armazenado na pasta "backup.0", recomeçando o ciclo.
Se o script fosse executado todos os dias ao longo de uma semana, começando na segunda-feira, quando chegasse no domingo a pasta "backup.0" armazenaria o backup do domingo, a "backup.1" o do sábado e assim por diante, até chegar na "backup.6", que armazenaria o backup da segunda-feira anterior.
Como as pastas são na verdade conjuntos de hard links para os arquivos da pasta "backup.0", o espaço ocupado em disco seria equivalente ao de um único backup completo e não de sete.
Adaptando o script anterior para este novo conceito, teríamos o seguinte:
#! /bin/sh
mount /dev/sdb1 /mnt/sdb1
# Cria a pasta para o caso do script ser executado pela primeira vez:
mkdir /mnt/sdb1/backup.0 &>/dev/null
# Rotaciona as pastas anteriores:
rm -rf backup.6
mv backup.5 backup.6
mv backup.4 backup.5
mv backup.3 backup.4
mv backup.2 backup.3
mv backup.1 backup.2
# Faz a cópia usando o cp -al:
cp -al backup.0 backup.1
# Atualiza o backup na pasta backup.0:
rsync -av --delete /var/ /mnt/sdb1/backup.0/ >> /tmp/rsync.log
rsync -av --delete /home/ /mnt/sdb1/backup.0/ >> /tmp/rsync.log
rsync -av --delete /var/ /mnt/sdb1/backup.0/ >> /tmp/rsync.log
# Ao terminar, desmonta a partição e ativa o gerenciamento de energia:
umount /mnt/sdb1; hdparm -S 24 /dev/sdb
Este processo funciona bem para arquivos que foram criados e deletados (remover um arquivo da pasta original não o apaga das pastas com as cópias feitas usando o "cp -al"). A principal limitação desse processo é que, como na realidade existe apenas uma cópia do arquivo, quando o arquivo é atualizado todos hard links passam a apontar para a versão mais recente. Ou seja, se um usuário deletou um arquivo, você seria capaz de recuperá-lo 5 dias depois sem problemas, mas se ele precisa de uma versão anterior do arquivo, a situação se complica.
Em outras palavras, o fato de remover o arquivo da pasta "backup.0" não apaga as cópias armazenadas nas pastas anteriores; o arquivo é deletado do HD apenas se você remove todos os hard links que apontam pra ele. Este é o grande atrativo de usar hard links: você tem múltiplas cópias do arquivo sem ter que arcar com o espaço adicional. A grande limitação é que, diferente de ao usar múltiplas cópias completas, que você não tem como reverter alterações feitas nos arquivos, apenas recuperar arquivos deletados.
Devido a isso, é importante combinar o sistema de rotacionamento com backups semanais completos, de preferência arquivados em um local diferente, ou gravados em alguma mídia removível, como no caso dos DVDs e das fitas DAT.
Você poderia ter, então, dois scripts de backup, um executado todos os dias, fazendo o backup incremental e outro executado uma vez por semana, fazendo o backup completo. Ao agendá-los no cron, você teria uma configuração similar a essa:
59 4 * * * root /usr/local/bin/backup-incremental
59 6 * * 0 root /usr/local/bin/backup-completo
Com isso, o backup incremental seria feito todos os dias às 4:59, enquanto o backup completo seria feito apenas no domingo às 6:59. Veja que os scripts foram propositalmente agendados para serem executados em horários diferentes, para que o sistema tenha tempo de terminar o backup incremental do domingo antes de executar o script do backup completo.
O rsync pode ser também usado remotamente. Originalmente ele não utiliza nenhum tipo de criptografia, o que faz com que ele não seja muito adequado para backups via internet. Mas este problema pode ser resolvido com a ajuda do SSH, que pode ser utilizado como meio de transporte. Não é à toa que o SSH é chamado de canivete suíço, ele realmente faz de tudo.
Neste caso o comando ficaria um pouco mais complexo:
$ rsync -av --rsh="ssh -l gdh" /mnt/arquivos gdh@192.168.1.1:/mnt/backup/
Veja que foi adicionado um parâmetro adicional, o --rsh="ssh -l gdh", que orienta o rsync a utilizar o SSH como meio de transporte. O "-l gdh" orienta o SSH a se conectar ao servidor remoto usando o login "gdh". Naturalmente, para que o comando funcione, é preciso que o servidor esteja com o SSH habilitado e você tenha um login de acesso. Em seguida, vem a pasta local com os arquivos, o endereço IP (ou domínio) do servidor e a pasta (do servidor) para onde vão os arquivos.
Uma observação é que usando apenas os parâmetros "-av", o rsync se limita a atualizar e a gravar novos arquivos na pasta do servidor, sem remover arquivos que tenham sido deletados na pasta local. Por um lado isto é bom, pois permite recuperar arquivos deletados acidentalmente, mas por outro pode causar confusão. Se você preferir que os arquivos que não existem mais sejam deletados, adicione o parâmetro "--delete", que usamos no tópico anterior, como em:
$ rsync -av --delete --rsh="ssh -l gdh" /mnt/arquivos gdh@192.168.1.1:/mnt/backup/
Para recuperar o backup, basta inverter a ordem do comando, como em:
$ rsync -av --rsh="ssh -l gdh" gdh@192.168.1.1:/mnt/backup/ /mnt/arquivos
Você pode também ativar o uso de compressão, de forma a reduzir o volume de bytes transferidos. Isso é útil sobretudo ao fazer backup de bases de dados do MySQL ou de pastas com arquivos html, que geralmente suportam um bom índice de compressão. Para isso, basta adicionar o parâmetro "z", como em:
$ rsync -avz --rsh="ssh -l gdh" gdh@gdhn.com.br:/var/www/gdhn /mnt/backup/
Neste exemplo, salvamos uma cópia da pasta "/var/www/gdhn" do servidor "gdhn.com.br" no diretório local "/mnt/backup/", fazendo um backup local dos arquivos do site.
Originalmente, você vai precisar fornecer a senha de acesso ao servidor cada vez que executar o comando, o que impossibilita seu uso em scripts de backup automático. Para automatizar a conexão, a melhor solução é usar um par de chaves do SSH com a passphrase em branco, assim como no exemplo do backup automático usando o tar do exemplo anterior.
Imagine que você quer fazer um backup completo de todos os arquivos dentro da pasta "/var/www" do servidor A no servidor B, de forma que o tráfego web possa ser rapidamente desviado para ele em caso de problemas com o primeiro servidor.
O primeiro passo seria criar um novo usuário no servidor B, que permitirá o acesso aos arquivos por parte do servidor A, como em "adduser backup".
O passo seguinte seria gerar as chaves do SSH (no servidor A), com o comando "ssh-keygen -t rsa" usando o login do usuário que executará o script de backup (e deixando a passphrase em branco) e instalar a chave pública no servidor B, usando o comando:
# ssh-copy-id -i ~/.ssh/id_rsa.pub backup@servidorB
Até aqui os passos são os mesmos que vimos no tópico sobre o tar, já que apenas refizemos os passos para automatizar a autenticação do SSH. Falta agora apenas escrever o script de backup, que fará o sincronismo. Se você não precisar que o script faça checagens adicionais, ele poderia ter uma única linha, como em:
#!/bin/sh
rsync -avz --delete --rsh="ssh -l backup" /var/www backup@servidorB:/var/www/
Diferente do comando anterior, destinado a fazer uma cópia local do diretório "/var/www/gdhn" do servidor remoto, este script (que seria executado pelo servidor A) copia diretamente todos os arquivos da pasta "/var/www" para o servidor B, de forma que ele funcione como um espelho.
Uma observação importante é que o usuário "backup" no servidor B deve ter permissão de escrita na pasta "/var/www", do contrário o sincronismo não vai funcionar por falta de permissões.
Caso a idéia seja fazer com que as modificações feitas no servidor A sejam replicadas rapidamente para o servidor B (imagine o caso de um sistema de balanceamento de carga entre os dois servidores, por exemplo), você poderia usar o parâmetro "*/5" no campo de minutos ao incluir o trabalho no "/etc/crontab" (de forma que o script fosse executado a cada 5 minutos), como em:
*/5 * * * * root /usr/local/bin/script-rsync
Fazendo backup das bases de dados do MySQL: Uma das grandes dúvidas de qualquer administrador iniciante é como fazer backup das bases de dados do MySQL, já que os dados são gravados e acessados através do servidor MySQL e não diretamente através de arquivos, como no caso dos arquivos referentes aos sites, salvos na pasta "/var/www", por exemplo.
As bases de dados do MySQL são salvas por padrão dentro da pasta "/var/lib/mysql". Ao criar a base de dados "phpbb", por exemplo, será criada a pasta "/var/lib/mysql/phpbb", contendo um conjunto de arquivos, referentes às tabelas criadas.
A forma mais simples de fazer backup das bases de dados do MySQL é simplesmente salvar o conteúdo da pasta "/var/lib/mysql", criando um arquivo .tar.gz ou mesmo copiando os arquivos diretamente para outra partição. O maior problema é que as bases de dados são alteradas continuamente durante a operação do banco de dados, o que leva a cópias inconsistentes. Se alguns dos arquivos dentro da pasta com a base mudam no meio da cópia, o backup conterá uma mistura de dados novos e antigos, uma receita para o desastre.
A forma mais segura é parar o serviço do MySQL antes de fazer o backup, garantindo assim que nada será alterado durante a cópia, como no exemplo abaixo:
# /etc/init.d/mysql stop
# tar -zcvf mysql.tar.gz /var/lib/mysql/
# /etc/init.d/mysql start
Um exemplo de script de backup simples para fazer um backup completo dos arquivos da pasta "/var/www", contendo os arquivos de todos os sites hospedados no servidor, e também da base de dados do MySQL, incluindo as datas em que os backups foram realizados nos nomes dos arquivos, seria:
#!/bin/sh
# Acessa a pasta onde os backups serão salvos:
cd /var/backup
# Cria uma variável contendo a data atual:
DATA=`date +%Y-%m-%d-%H.%M`
# Faz backup da pasta /var/www:
tar -zcvf www-$DATA.tar.gz /var/www
# Pára o MySQL e faz backup das bases de dados:
/etc/init.d/mysql stop
tar -zcvf mysql-$DATA.tar.gz /var/lib/mysql
/etc/init.d/mysql start
Ao executar o script, você teria dois arquivos, como em "www-2008-06-27-07.21.tar.gz" e "mysql-2008-06-27-07.21.tar.gz". Veja que a data incluída nos nomes dos arquivos propositalmente inclui também a hora e os minutos em que foram gerados, de forma que você saiba exatamente quando os arquivos foram gerados e obtenha sempre arquivos de nomes diferentes, mesmo que o script seja executado várias vezes em seqüência.
Para automatizar a execução do script, você pode adicionar uma entrada no arquivo "/etc/crontab", assim como fizemos nos exemplos anteriores:
59 4 * * * root /usr/local/bin/script-backup
Esta entrada faria com que o script fosse executado todos os dias às 4:59 da manhã, sempre gerando dois novos arquivos com a data de quando foram executados. Com isso, ficaria faltando apenas copiar ou mover os arquivos regularmente para outro servidor, onde eles ficarão arquivados.
Um script como esse sem dúvidas pode resolver seu problema de forma simples. Você poderia incluir linhas adicionais para que o backup incluísse outras pastas do sistema, como por exemplo os diretórios com os logs. O problema com essa abordagem é que cada vez que o script é executado o servidor MySQL ficará fora do ar durante alguns segundos (ou minutos). Se a base de dados é usada pelo site da sua empresa, por exemplo, ele ficará fora do ar até que o backup seja concluído e o servidor MySQL volte a ser iniciado.
Agendar o backup usando o cron de forma que ele seja feito durante a madrugada (quando o tráfego é menor), minimiza o problema, mas não o soluciona completamente, já que, independentemente do horário, você vai acabar sempre perdendo algumas visitas.
A segunda opção é fazer um backup online, sem parar o servidor. O utilitário mais simples (e provavelmente o mais usado) para isso é o mysqldump, que acompanha o pacote principal do MySQL.
Diferente do método anterior, onde os arquivos são copiados diretamente, o mysqldump acessa o banco de dados por vias normais, da mesma forma que um aplicativo qualquer faria. Em outras palavras, ele não lê os arquivos, mas sim as informações armazenadas nas bases de dados. Isso permite que o backup seja consistente, mesmo que as bases de dados sejam alteradas durante o backup.
Para salvar todas as bases de dados do servidor no arquivo "backup.sql", criado no diretório atual, por exemplo, o comando seria:
# mysqldump -u root -p -x -e -A > backup.sql
O "-u root -p" especifica o usuário que será usado para acessar o banco de dados. No exemplo estou fazendo um backup completo, por isso estou usando diretamente o root. A opção "-x" trava as bases de dados no momento em que cada uma é copiada, evitando qualquer problema de inconsistência, enquanto a "-e" é uma opção de otimização, que permite ao mysqldump combinar argumentos INSERT dentro das tabelas, o que torna tanto o backup quanto a restauração mais rápidos. Finalizando, a opção "-A" especifica um backup completo, de todas as bases de dados.
Se o comando parasse por aí, o mysqldump simplesmente escreveria todo o conteúdo das bases de dados na própria janela do terminal, resultando em uma longa exibição de informações, sem muita utilidade. Como queremos que a saída seja salva em um arquivo, usamos o ">", que redireciona a saída para o arquivo especificado.
O arquivo "backup.sql" gerado é basicamente um arquivo de texto gigante contendo declarações de todas as informações armazenadas. Você pode reduzir o tamanho do arquivo para um quarto (ou menos) do tamanho original compactando o arquivo, o que pode ser feito adicionando a opção "| gzip" antes do ">" no comando, como em:
# mysqldump -u root -p -x -e -A | gzip > backup.sql.gz
Note que nesse exemplo adicionei também o ".gz" no nome do arquivo, indicando que se trata de um arquivo compactado. Para usá-lo posteriormente, você precisaria apenas descompactar o arquivo, usando o comando "gunzip", como em:
# gunzip backup.sql.gz
O maior problema com estes dois comandos é que você precisa digitar a senha do MySQL depois de rodar o comando, o que dificulta seu uso em scripts de backup automático. É possível eliminar a necessidade de digitar a senha especificando-a diretamente no comando, depois do "-p" (sem espaços), como em:
# mysqldump -u root -p12345 -x -e -A | gzip > backup.sql.gz
Um exemplo de script simples de backup automático usando o comando acima seria:
#!/bin/sh
cd /var/backup
DATA=`date +%Y-%m-%d-%H.%M`
# Faz backup das bases de dados usando o mysqldump
mysqldump -u root -p12345 -x -e -A | gzip > backup-$DATA.sql.gz
Se você gerou um par de chaves no SSH sem passphrase e instalou a chave pública no servidor de backup remoto, como vimos anteriormente, poderia adicionar as linhas abaixo no final do script para que o arquivo fosse automaticamente movido para o servidor de backup remoto no final do processo:
scp backup-$DATA.sql.gz usuario@servidor-de-backup:/mnt/backups/
rm -f backup-$DATA.sql.gz
O passo final seria adicionar uma entrada no cron para automatizar a execução do script. Para que ele fosse executado todas as segundas, quartas e sextas às 22:58 (para o exemplo ficar diferente do anterior :) a linha no arquivo "/etc/crontab" seria:
58 22 * * 1,3,5 root /usr/local/bin/script-backup
Note que ao incluir senhas em arquivos, é extremamente importante restringir as permissões, de forma que apenas o root (ou o usuário em questão) tenha permissão para lê-lo. Qualquer outro usuário do servidor que tenha acesso de leitura no arquivo, poderá ler a senha e acessar o servidor MySQL:
# chmod 700 /usr/local/bin/script-backup
Usando o "700" os demais usuários não poderão ver nem executar o arquivo, o que seria o ideal no nosso exemplo, já que a entrada no crontab faz com que ele seja executado usando a conta de root. Se você quiser que outros usuários possam executar o arquivo manualmente quando necessário, mas ainda assim sem poder ver a senha armazenada dentro dele, o ideal seria criar um grupo, adicionar os usuários desejados dentro dele e setar as permissões do arquivo para "710", onde os usuários que fazem parte do grupo podem apenas executar o arquivo, sem ver seu conteúdo. Os comandos seriam:
# addgroup backup-sql
# adduser joao backup-sql
# adduser joaquim backup-sql
# chown root:backup-sql /usr/local/bin/script-backup
# chmod 710 /usr/local/bin/script-backup
Voltando ao tema principal, o "mysqldump -u root -p -x -e -A" permite fazer um backup completo de todas as bases do servidor, que poderia ser usado para restaurar os dados em uma instalação limpa do MySQL. É possível também fazer backups localizados, contendo apenas uma base de dados específica.
Nesse caso, em vez de usar a opção "-A", você usaria a opção "-B", seguida pela base de dados a ser salva, como em:
# mysqldump -u root -p -x -e -B phpbb > phpbb.sql
Na hora de restaurar o backup, deixamos de usar o mysqldump e passamos a utilizar o cliente mysql, que se encarrega de ler os comandos e os dados adicionados nos arquivos e usá-los para povoar as bases de dados. O comando ficaria então:
# mysql -u root -p --database=phpbb < phpbb.sql
Você pode também especificar a senha diretamente no comando, assim como no caso do mysqldump, como em:
# mysql -u root -p12345 --database=phpbb < phpbb.sql
Se você tentar restaurar o backup sobre uma base de dados contendo dados, provavelmente receberá uma mensagem de erro logo no início do processo, avisando que uma das tabelas já existe, como em:
ERROR 1050 at line 19: Table 'wp_comments' already exists
A solução no caso é remover a base de dados antiga usando o cliente MySQL e criar outra em branco para então fazer a restauração, como em:
# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 18
Server version: 5.0.32-Debian_7etch5-log Debian etch distribution
Type 'help;' or 'h' for help. Type 'c' to clear the buffer.
mysql> DROP DATABASE phpbb;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE DATABASE phpbb;
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
# mysql -u root -p --database=phpbb < phpbb.sql
Outra opção seria adicionar a opção "--add-drop-table" ao gerar o backup com o mysqldump. Ela faz com que ele inclua instruções para que as bases sejam excluídas e recriadas automaticamente durante a restauração, evitando que você precise fazê-lo manualmente. O comando ficaria então:
# mysqldump --add-drop-table -u root -p -x -e -B phpbb > phpbb.sql
O comando para restaurar continua o mesmo, com a diferença de que você não precisa mais usar os comandos "DROP DATABASE;" e "CREATE DATABASE;" antes de fazer a restauração.
Esta opção pode ser adicionada também ao comando para fazer o backup completo das bases de dados, facilitando assim sua restauração:
# mysqldump --add-drop-table -u root -p -x -e -A > backup.sql
O backup poderia ser então restaurado diretamente usando o comando abaixo, sem que você precisasse remover as bases e tabelas manualmente antes de iniciar a recuperação:
# mysql -u root -p < backup.sql
O backup usando o mysqldump e a restauração usando o mysql são preferíveis à cópia manual dos arquivos da pasta "/var/lib/mysql", pois evita problemas de incompatibilidade ao migrar os dados para versões diferentes do MySQL. Além disso, a facilidade de fazer o backup sem precisar parar o servidor é uma grande vantagem em um ambiente de produção.