Solução simples de backup

6

Estou procurando um script / pacote de backup muito básico para um diretório no meu servidor Ubuntu. Atualmente estou usando um cronjob assim:

0 5 * * 1 sudo tar -Pzcf /var/backups/home.tgz /home/

Mas quero uma solução que adicione um registro de data e hora ao nome do arquivo e não substitua os backups antigos. É claro que isso vai inundar minha unidade lentamente para que backups antigos (por exemplo, mais de dois meses) precisem ser excluídos automaticamente.

Felicidades, Dennis

ATUALIZAÇÃO: Eu decidi dar a recompensa para a logrotate -solution por causa da sua simplicidade. Mas muito obrigado a todos os outros respondentes também!

    
por wottpal 26.04.2018 / 10:51

4 respostas

4

Solução simples usando logrotate

Se você quiser mantê-lo simples e sem script, fique com o seu cronjob atual e configure também uma regra de logrotate para ele.

Para fazer isso, coloque o seguinte em um arquivo chamado /etc/logrotate.d/backup-home :

/var/backups/home.tgz {
    weekly
    rotate 8
    nocompress
    dateext
}

De agora em diante, sempre que o logrotate for executado (e normalmente será feito todos os dias às ~ 6: 25h), ele verificará se é adequado para rotação e, em caso afirmativo, renomeie seu home.tgz para outro arquivo com um timestamp adicionado. Ele manterá 8 cópias dele, então você tem aproximadamente dois meses de história.

Você pode personalizar o timestamp usando a opção dateformat , veja logrotate (8) .

Como seu trabalho de backup é executado às 5h e o logrotate é executado às 6:25, você deve garantir que o backup do tar seja executado bem abaixo de 1h e 25m (acho que será muito mais rápido).

    
por Sebastian Stark 01.05.2018 / 00:12
5

Esta é (uma variante do) script que eu uso ( /home/pduck/bup.sh ):

#!/usr/bin/env bash

src_dir=/home/pduck
tgt_dir=/tmp/my-backups
mkdir -p $tgt_dir

# current backup directory, e.g. "2017-04-29T13:04:50";
now=$(date +%FT%H:%M:%S) 

# previous backup directory
prev=$(ls $tgt_dir | grep -e '^....-..-..T..:..:..$' | tail -1); 

if [ -z "$prev" ]; then
    # initial backup
    rsync -av --delete $src_dir $tgt_dir/$now/
else
    # incremental backup
    rsync -av --delete --link-dest=$tgt_dir/$prev/ $src_dir $tgt_dir/$now/
fi

exit 0;

Ele usa rsync para copiar localmente os arquivos do meu diretório inicial para um local de backup, /tmp/my-backups no meu caso. Abaixo desse diretório de destino, é criado um diretório com o timestamp atual, por exemplo, /tmp/my-backups/2018-04-29T12:49:42 e abaixo desse diretório o backup desse dia é colocado.

Quando o script é executado novamente, ele percebe que já existe um diretório /tmp/my-backups/2018-04-29T12:49:42 (escolhe o diretório "mais recente" que corresponde ao padrão de registro de data e hora). Em seguida, ele executa o comando rsync , mas desta vez com a opção --link-dest=/tmp/my-backups/2018-04-29T12:49:42/ para apontar para o backup anterior.

Este é o ponto real de fazer backups incrementais:

Com --link-dest=… rsync não copia arquivos inalterados em comparação com os arquivos no diretório link-dest. Em vez disso, apenas cria hardlinks entre os arquivos atuais e os arquivos anteriores.

Quando você executa esse script 10 vezes, você obtém 10 diretórios com os vários carimbos de data / hora e cada um contém um instantâneo dos arquivos nesse momento. Você pode navegar pelos diretórios e restaurar os arquivos desejados.

O serviço de limpeza também é muito fácil: apenas rm -rf do diretório de timestamp que você não deseja manter. Isso não removerá arquivos mais antigos ou mais recentes ou inalterados, apenas remova (diminua) os hardlinks. Por exemplo, se você tiver três gerações:

  • /tmp/my-backups/2018-04-29T...
  • /tmp/my-backups/2018-04-30T...
  • /tmp/my-backups/2018-05-01T...

e deletar o segundo diretório, então você perde o snapshot daquele dia, mas os arquivos ainda estão no primeiro ou no terceiro diretório (ou ambos).

Eu coloquei um cronjob em /etc/cron.daily que diz:

#!/bin/sh
/usr/bin/systemd-cat -t backupscript -p info /home/pduck/bup.sh

Nomeie o arquivo backup ou algo assim, chmod +x , mas omita o sufixo .sh (não será executado, em seguida). Devido a /usr/bin/systemd-cat -t backupscript -p info , você pode assistir ao progresso via journalctl -t backupscript .

Observe que essa solução rsync exige que o diretório de destino esteja em um sistema de arquivos ext4 devido aos hardlinks.

    
por PerlDuck 29.04.2018 / 13:11
3

Com uma pequena edição no seu comando cron, você pode adicionar um timestamp ao nome do arquivo:

0 5 * * 1 sudo tar -Pzcf /var/backups/home_$(date "+%Y-%m-%d_%H-%M-%S").tgz /home/

E quanto à limpeza, encontrei um incrível script de uma linha aqui que adaptei ao seu caso:

find . -type f -name 'home_*.tgz' -exec sh -c 'bcp="${1%_*}"; bcp="${bcp#*_}"; [ "$bcp" "<" "$(date +%F -d "60 days ago")" ] && rm "$1"' 0 {} \;

Você pode adicionar o comando acima a outra tarefa do cron e remover backups com mais de 60 dias. HTH

    
por Eskander Bejaoui 30.04.2018 / 00:56
3

Aqui é parte de uma solução do meu script de backup diário que é chamado pelo cron: Backup de configuração do Linux, scripts e documentos para o Gmail . O script completo está adequado porque:

  • inclui arquivos /home/me/* segmentados, mas ignora 1 GB de arquivos /home/ importantes para você usados pelo FireFox, Chrome e outros aplicativos que não tenho interesse em fazer backup.
  • inclui arquivos importantes para mim, mas sem importância para você em /etc/cron* , /etc/system* , /lib/systemd/system-sleep , /etc/rc.local , /boot/grub , /usr/share/plymouth , /etc/apt/trusted.gpg , etc.
  • ele envia e-mails para o backup todas as manhãs na minha conta do gmail.com para backups fora do site. Seus backups não são apenas no site, mas também na mesma máquina.

Aqui está o script relevante, partes das quais você pode adaptar:

#!/bin/sh
#
# NAME: daily-backup
# DESC: A .tar backup file is created, emailed and removed.
# DATE: Nov 25, 2017.
# CALL: WSL or Ubuntu calls from /etc/cron.daily/daily-backup
# PARM: No parameters but /etc/ssmtp/ssmtp.conf must be setup

# NOTE: Backup file name contains machine name + Distro
#       Same script for user with multiple dual boot laptops
#       Single machine should remove $HOSTNAME from name
#       Single distribution should remove $Distro

sleep 30 # Wait 30 seconds after boot

# Running under WSL (Windows Subsystem for Ubuntu)?
if cat /proc/version | grep Microsoft; then
    Distro="WSL"
else
    Distro="Ubuntu"
fi

today=$( date +%Y-%m-%d-%A )
/mnt/e/bin/daily-backup.sh Daily-$(hostname)-$Distro-backup-$today

Meu gmail.com está com apenas 35% do total (em 15 GB), então meus backups diários podem ser executados por mais algum tempo antes que eu precise excluir arquivos. Mas em vez de uma filosofia "tudo mais antigo que xxx", usarei uma estratégia de pai-filho-filho como descrito aqui: É necessário manter registros dos meus backups? . Em resumo:

  • de segunda a domingo (backups diários) que são eliminados após 14 dias
  • Backups de domingo (backups semanais) expurgados após 8 semanas
  • Backups do último dia do mês (backups mensais) removidos após 18 meses
  • Backups do último dia do ano (backups anuais) mantidos para sempre

Meu processo de limpeza será complicado pelo fato de que vou ter que aprender Python e instalar uma biblioteca Python para gerenciar pastas do Gmail.

Se você não quiser backups geracionais e quiser limpar arquivos com mais de 2 meses, essa resposta ajudará: Encontre não removendo arquivos em pastas através do script bash .

Em resumo:

DAYS_TO_KEEP=60
find $BACKUP_DIR -maxdepth 1 -mtime +"$DAYS_TO_KEEP" -exec rm -rf {} \;
    
por WinEunuuchs2Unix 30.04.2018 / 01:22