#!/bin/bash# Este programa faz backups das bases de dados de qq servidor e dos# arquivos do servidor local ou de arquivos montados via samba para um diretório# no servidor local.# Autor: Felipe Rafael Prenholato# Data: Wed Sep 6 21:52:35 BRT 2006# E-Mail: philipe_rp@yahoo.com.br / chronos@gentoobr.org# Este script está coberto pela GPLv2.# Use por sua conta e risco.# Configure aqui o diretório onde serão arquivados os backups antigos.# BACKUP_ARCHIVE_ROOT='/opt/backup-archives'BACKUP_ARCHIVE_ROOT='/opt/backup-archives'# Configure aqui o tempo que os backups devem ficar arquivados, em dias.ARCHIVE_DAYS=3# Configure aqui o diretório onde serão arquivos os backups atuais.# BACKUP_ROOT='/opt/backup'BACKUP_ROOT='/opt/backup'# Configure aqui os diretórios que terão seus backups feitos. Deve ser um por# linha.BACKUP_DIRS='/home/handrus/etc'# Configure aqui o diretório onde vai ser feito os dumps do Postgres. Ele ficara# dentro de $BACKUP_ROOT.PSQL_ROOT='pg-dump'# Configure aqui o host e a porta onde estão as bases do postgresql.# Serão feitos backups de todas as bases, uma com cada arquivo bzip2.# Mais de um host? Coloque um por linha. Precisa colocar porta, separe por ':',# ex:# PSQL_HOST='localhost:5432# cerbero:666'PSQL_HOST='localhost:5432local'# Configure aqui opções como porta e usuário do postgres por exemplo.# Estas confs são usadas para o psql e o pg_dumpPSQL_OPTS='-U postgres'# Source /sbin/functions.sh pra deixar o script mais 'bonitinho' :].# Quando rodar no cron e ir para o e-mail não vai ter cores e os caracteres aqui# vão todos certos.source /sbin/functions.sh# Umask default para o scriptumask 002# Função para checar permissionamento do diretório.checaDir() { if [ -d $1 ] && [ -e $1 ] && [ -r $1 ] && [ -w $1 ] && [ -x $1 ] then eend 0 else if [ ! -d $1 ] && [ ! -e $1 ] then eend 1 echo " $(ewarn 'O diretório não existe, criando '$1)" mkdir -p $1 &>/dev/null sts=$? eend $sts if [ "$sts" != "0" ] then echo " $(eerror 'O diretório não pode ser criado, pode haver um arquivo com o mesmo nome ou não haver permissões para cria-lo')" exit 1 fi fi if [ ! -r $1 ] || [ ! -w $1 ] || [ ! -x $1 ] then eend 1 echo " $(eerror 'O diretório tem permissões incorretas.')" echo " $(eerror 'Use chmod para corrigir e rode o script novamente.')" fi fi}# Body do scriptebegin "Checando $BACKUP_ARCHIVE_ROOT"checaDir $BACKUP_ARCHIVE_ROOTechoebegin "Checando $BACKUP_ARCHIVE_ROOT/$PSQL_ROOT"checaDir $BACKUP_ARCHIVE_ROOT/$PSQL_ROOTechoebegin "Checando $BACKUP_ROOT"checaDir $BACKUP_ROOTechoebegin "Checando $BACKUP_ROOT/$PSQL_ROOT"checaDir $BACKUP_ROOT/$PSQL_ROOT# Backup start dateBACKUP_START=$(date)echoebegin "Iniciando backup em $BACKUP_START"# Arquivando backups de diretórios existentesebegin "Arquivando backups de diretórios existentes"archs=$(find $BACKUP_ROOT -maxdepth 1 -type f -name '*.bz2')for e in $archsdo echo " $(einfo 'Arquivando '$e)" mv $e* $BACKUP_ARCHIVE_ROOT &>/dev/null eend $?done# Arquivando backups de basesebegin "Arquivando backups de bases de dados existentes"archs=$(find $BACKUP_ROOT/$PSQL_ROOT -type f -name '*.bz2')i=0erro=0for e in $archsdo i=$(($i+1)) mv $e* $BACKUP_ARCHIVE_ROOT/$PSQL_ROOT >> $BACKUP_ARCHIVE_ROOT'/'$PSQL_ROOT'/archivelog' sts=$? [ "$sts" != "0" ] && erro=1doneif [ "$erro" == "1" ]then eend 1 echo " $(eerror 'Problemas no arquivamento das bases de dados.')" echo " $(eerror 'Log em '$BACKUP_ARCHIVE_ROOT'/'$PSQL_ROOT'/archivelog.')"else eend 0 echo " $(einfo $i' bases arquivadas.')"fi# Removendo os logsebegin "Removendo os logs dos backups arquivados"find $BACKUP_ARCHIVE_ROOT -type f -name '*log' -exec rm {} \; &>/dev/nulleend $?# Removendo backups arquivados com mais de $ARCHIVE_DAYSebegin "Removendo backups velhos"archs=$(find $BACKUP_ARCHIVE_ROOT -type f -cmin $ARCHIVE_DAYS)i=0erro=0date >> $BACKUP_ARCHIVE_ROOT'/clearlog'for e in $archsdo i=$(($i+1)) rm $e -f -v >> $BACKUP_ARCHIVE_ROOT'/clearlog' sts=$? [ "$sts" != "0" ] && erro=1doneif [ "$erro" == "1" ]then eend 1 echo " $(eerror 'Problemas na remoção dos arquivos antigos.')" echo " $(eerror 'Log em '$BACKUP_ARCHIVE_ROOT'/clearlog.')"else eend 0 echo " $(einfo $i' backup removidos.')"fi# Backup dos diretóriosechoebegin "Iniciando backup dos diretórios "for dir in $BACKUP_DIRSdo bn=$(date +%Y%m%d_%Hh%Mm)${dir//\//-}'.tar.bz2' echo " $(einfo 'Backup de '$dir' em '$BACKUP_ROOT'/'$bn)" tar jcf $BACKUP_ROOT/$bn $dir &> $BACKUP_ROOT/$bn'.log' sts=$? if [ "$sts" != "0" ] then eend 1 echo " $(eerror 'Problemas no backup de '$dir'.')" echo " $(eerror 'Verifique o log em '$BACKUP_ROOT'/'$bn'.log.')" else eend 0 echo " $(einfo 'Gerando MD5')" md5sum $BACKUP_ROOT/$bn > $BACKUP_ROOT/$bn'.md5' 2>/dev/null eend $? fidone# Backup das bases de dados Postgresechoebegin "Iniciando backup de bases Postgresql"PSQL_ROOT=$BACKUP_ROOT'/'$PSQL_ROOTfor psqlhost in $PSQL_HOSTdo # Eu não usei cut -d: -f2 porque ele imprimia o mesmo que -f1. o awk retorna # uma string vazia. host=$(echo $psqlhost | awk -F: '{print $1}') textport=$(echo $psqlhost | awk -F: '{print $2}') count=$(echo $textport | wc -c) [ $count -gt 1 ] && port=" -p $textport " TMPDIR=$BACKUP_ROOT'/tmp_'$host [ ! -e $TMPDIR ] && mkdir $TMPDIR &>/dev/null TMPLST=$TMPDIR'/bdlist' echo " $(ebegin 'Backup de '$host$( [ $count -gt 1 ] && echo ' na porta '$textport))" echo " $(ebegin 'Testando acesso a '$host)" # Não filtro com cut aqui porque vai zoar o $? e eu não confio mto em # $PIPESTATUS psql $PSQL_OPTS -l -A -t -h $host $port &> $TMPLST sts=$? # Po ... fodeu ... kd o server O_o! if [ "$sts" != "0" ] then eend 1 echo " $(eerror 'O servidor '$host' não pode ser acessado.')" echo " $(eerror 'Verifique se o servidor postgres esta configurado corretamente.')" echo " $(eerror 'O acesso é feito via metodo trust e o usuário postgres deve estar')" echo " $(eerror 'habilitado para este IP. Conexões tcp/ip devem estar ativadas.')" else eend 0 # end para 'Testando acesso' # Para cada base do host faz o dump em um arquivo com o nome de # data_host_base.sql, ai compacta com bzip2 -z9 e depois faz um md5. for base in $(cat $TMPLST | cut -d'|' -f1 | egrep -v '^template[01]$') do bn=$(date +%Y%m%d_%Hh%Mm)'_'$host'_'$base'.sql' # Dumping echo " $(ebegin 'Dumping '$base' para '$bn)" pg_dump $PSQL_OPTS -h $host $port -O -i $base > $PSQL_ROOT/$bn 2> $PSQL_ROOT/$bn'.error_log' sts=$? if [ "$sts" != "0" ] then # Fodeu ... eend 1 echo " $(eerror 'Problemas no Dump da base.')" echo " $(eerror 'Log em '$PSQL_ROOT'/'$bn'.error_log')" else # Uha ... hora de compactar. eend 0 echo " $(ebegin 'Gerando '$bn'.bz2')" echo "bzip2" >> $PSQL_ROOT/$bn'.error_log' bzip2 -z9 $PSQL_ROOT/$bn >> $PSQL_ROOT/$bn'.error_log' 2>&1 sts=$? if [ "$sts" != "0" ] then # -_- ... echo " $(eerror 'Erro na compactação.')" echo " $(eerror 'Log em '$PSQL_ROOT'/'$bn'.error_log')" else echo " $(einfo 'Gerando md5')" md5sum $PSQL_ROOT/$bn.bz2 > $PSQL_ROOT/$bn'.bz2.md5' 2>/dev/null eend $? fi fi done fi rm -r $TMPDIR $TMPLST &>/dev/nulldone# Backup end dateBACKUP_END=$(date)echoeinfo "Backup terminado em $BACKUP_END"exit