Backup automático de bancos de dados MySql em repositórios Git no Ubuntu Artigo

Conheça os cursos gratuitos do WebDevBr! - Inscreva-se!


Este artigo foi publicado a 1 ano, 1 semana atrás.

Eu tenho um cloud na Digital Ocean com Ubuntu e (obviamente) faço backup dos bancos de dados, o grande problema é que eu fazia o backup localmente (no cloud) e desta forma não abrangia todas as possibilidades de segurança, já que se algo der errado com o sistema operacional eu posso não conseguir recuperar meus backups.

Pra ser completo eu preciso enviar para um local totalmente não relacionado com o meu servidor, preciso conseguir consultar e até baixar os arquivos rapidamente e ainda armazenar as diferentes versões dos arquivos. Logo a responsa foi óbvia pra mim, vou usar o DropBox (muita gente riu ai, né), eu tenho conta premium, posso criar um ShellScript pra guardar os últimos 3 backups e fica todo mundo feliz, mas é claro que eu desisti e resolvi usar Git.

O Git versiona os arquivo nativamente, eu não preciso de integrações complicadas com o terminal do Ubuntu, eu posso enviar para qualquer serviço de repositórios Git que eu quiser ou até para mais de um.

Gostou deste artigo?

Receba atualizações semanais com novos artigos do WebDevBr e outras dicas!

Cara!!! Eu posso clonar o repositório no meu computador e dar um git pull de vez em quando pra atualizar aqui no meu computador.

Mas vamos por partes, a primeira coisa é gerar o backup localmente.

Criando o script de backup

O meu script é simples (Shell Script não é bem o meu foco como programador), mas rola legal. Eu queria gerar um backup de todos os bancos separadamente e compactar cada um, assim eu não preciso abrir um arquivo enorme para ver um banco com 2 tabelas e meia dúvida de registros.

Criei um diretório para guardar meus backups e dentro um arquivo chamado run.sh com permição de execução, pra isso rodei os comandos a seguir:

mkdir database-backup
cd database-backup
>> run.sh
chmod +x run.sh

Bem simples, o primeiro comando cria o diretório, o segundo acessa o diretório, o terceiro cria o arquivo run.sh e o último da permissão de execução.

Em seguida eu editei o arquivo run.sh (eu uso o Vim) com o conteúdo a seguir:

Para abrir um arquivo no Vim use o comando vi [nome do arquivo], por exemplo: vi run.sh

Para começar inserir um texto no Vim precione a tecla i no teclado

#!/bin/bash

DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$DIRECTORY"

echo 'INICIANDO BACKUP'

echo 'Baixando bancos de dados'

echo 'Empacotando alterações'

echo "Enviando para o repositório remoto"

echo "Avisando administrador"

echo "BACKUP FINALIZADO"

Na primeira linha eu informo que vou usar o interpretador #!/bin/bash em seguida eu informo que tudo será realizado no diretório em que está o arquivo run.sh (linhas 3 e 4), dai pra baixo só tenho alguns comandos echo, ele apenas imprime textos no console, eu aproveitei para indicar os passos que vou usar para gerar o meu backup.

Na linha 2 (entre #!/bin/bash e DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )") vou informar algumas variáveis de configuração, assim fica fácil editar as configurações logo no começo do arquivo, por exemplo, vamos informar os dados de conexão com o banco de dados:

#!/bin/bash

MYSQL_USER="root"
MYSQL_PASS="1234"

DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$DIRECTORY"

#... resto do arquivo

Para salvar um arquivo no Vim pressione a tecla esc e depois digite :w

Para fechar um arquivo no Vim pressione a tecla esc e depois digite :q

Para salvar e fechar um arquivo no Vim pressione a tecla esc e depois digite :wq

Confirme os comandos a cima com a tecla enter

Fazendo backup do banco de dados localmente

Agora vou gerar os arquivos de backup e compactar cada um separadamente, pra isso vou:

  1. Trazer o nome de todos os bancos de dados
  2. Fazer um loop nesta lista
  3. Em cada entrada do loop vou rodar um mysqldump pra gerar o sql
  4. Compactar este sql com gzip

O script (que deve ficar logo após o echo 'Baixando bancos de dados') é o seguinte

for I in $(mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'show databases where `Database` not in("information_schema")');
do
        if [ "$I" != 'Database' ]
        then
                echo "- $I"
                mysqldump -u$MYSQL_USER -p$MYSQL_PASS --complete-insert "$I" > "$I".sql;
                gzip "$I".sql -f
        fi
done

Pronto, o arquivo já deve estar funcional, para testar rode o comando ./run.sh, o resultado deve ser um arquivo compactado para cada banco de dados presente no servidor.

Enviando para o repositório Git

Eu uso atualmente o BitBucket para esta tarefa, mas eu posso migrar a qualquer momento para o GitHub ou GitLab se quiser, tudo o que preciso é:

  1. Ter o Git Instalado no servidor (pode ser feito com sudo apt-get install git)
  2. Chave SSH configurada entre o servidor e o BitBucket (por exemplo)
  3. Configurar o remote no meu repositório local (local == servidor)

Para configurar a chave de acesso você pode procurar por um tutorial passo a passo que tanto o BitBucket, GitHub ou GitLab tem disponíveis para Ubuntu, Windows, Mac e, em alguns casos, traduzidos para português.

Aqui vou me manter simples e imaginar que você já tem a url ssh do repositório remoto e a chave ssh já configurada

Para criar o repositório local e informar qual o remoto usar, rode os comandos a seguir:

git init
git remote add origin git@bitbucket.org:user/repo.git

Não esqueça de trocar git@bitbucket.org:user/repo.git pelo endereço do seu repositório remoto.

Agora precisamos automatizar o commit e o envio dele para o servidor remoto, logo após echo 'Empacotando alterações' no run.sh coloque:

git add .
git commit -m "Backup $COMMIT_COUNT"

E isso gera um commit com a mensagem Backup {número do backup}, assim quando você checar os commits já vai saber quantos backups foram feitos olhando o último commit gerado.

Para mandar tudo para o servidor remoto e manter os arquivos seguramente fora do seu servidor apenas faça um git push, coloque o código a seguir após echo "Enviando para o repositório remoto"

git push -u origin master

Neste ponto você já terá o backup sendo enviado e com registro de versão diretamente no BitBucket, GitHub, GitLab ou qualquer repositório remoto que quiser usar.

Graças a chave ssh você não vai precisar digitar a senha do repositório, mesmo que seja privado (o ideal é que seja privado).

Rode ./run.sh para testar.

Avisando o administrador

Você também pode solicitar que o servidor dispare um email para você mesmo no fim do processo, avisado que tem um novo backup disponível, para isso eu usei o mailutils.

Para instalar o mailutils use o comando sudo apt-get install mailutils.

No começo do arquivo, logo após as configurações de acesso ao mysql coloque mais duas variáveis:

#!/bin/bash

MYSQL_USER="root"
MYSQL_PASS="1234"
MAIL="seu@emai.com"
REMOTE_REPOSITORY=https://bitbucket.org/usuario/repo

DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

#... resto do arquivo

E logo depois de echo "Avisando administrador" adicione:

mail -s "Backup do banco completo" $MAIL <<< "Para acessar o arquivo remoto vá até $REMOTE_REPOSITORY"

E prontinho, você também envia email avisando sobre o backup

Agendando a execução do Shell Script

Abra o arquivo /etc/crontab com o Vim ou o editor de texto que você prefirir e adicione a linha a seguir no final do arquivo:

59 23   * * *   root    /caminho/ate/o/schell-script/run.sh

Isso faz com que o arquivo run.sh seja rodado todos os dias as 23:59 (1 minuto para meia noite) e faça o processo de backup automaticamente e sem intervenção humana.

Conclusão

Neste ponto seu arquivo run.sh completo deve estar desfa forma:

#!/bin/bash

MYSQL_USER="root"
MYSQL_PASS="1234"
MAIL="seu@emai.com"
REMOTE_REPOSITORY=https://bitbucket.org/usuario/repo

DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$DIRECTORY"
COMMIT_COUNT=`git rev-list HEAD --count`
COMMIT_COUNT=$(($COMMIT_COUNT+1))

echo 'INICIANDO BACKUP'

echo 'Baixando bancos de dados'
for I in $(mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'show databases where `Database` not in("information_schema")');
do
        if [ "$I" != 'Database' ]
        then
                echo "- $I"
                mysqldump -u$MYSQL_USER -p$MYSQL_PASS --complete-insert "$I" > "$I".sql;
                gzip "$I".sql -f
        fi
done

echo 'Empacotando alterações'
git add .
git commit -m "Backup $COMMIT_COUNT"

echo "Enviando para o repositório remoto"
git push -u origin master

echo "Avisando administrador"
mail -s "Backup do banco completo" $MAIL <<< "Para acessar o arquivo remoto vá até $REMOTE_REPOSITORY"

echo "BACKUP FINALIZADO"

Espero ter ajudado!!!


* Parcelamento apenas cartão de crédito! Pode haver uma pequena variação no parcelamento em relação a simulações apresentadas!