Como Hacer Buenos Backups Usando Un Simple Script

14
06/09/13 #! /bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup) bourneagainshell.blogspot.mx/2009/02/to-backup.html 1/14 viernes, 20 de febrero de 2009 De como hacer buenos backups usando un simple script(o KISS bakcup) Supongamos un server recién instalado, llevó horas configurarlo, dejarlo afinado como un violín, pero cuando creemos haber terminado aún hay como una sensación, algo que no está bien, pero... que será? "Puede fallar" decía Tusam, y todos comprobamos la verdad de estas sabias palabras alguna vez en la vida. Pero...qué pude fallar? short answer: " todo puede fallar" Lo bueno es que muchas de las cosas son reemplazables, mother, memorias, fuentes, discos se consiguen a buen precio hoy, pero que hay de las horas de configuración?, los datos acumulados?, los emails?, las bases de datos? La posibilidad de que esa información valiosa se pierdan siempre ha sido un itch to scratch. -Indice 1- Objetivos 2- Requisitos 3- Desarrollo 3.1- Configuración 3.2- Setup inicial 3.3- Creando el backup 3.4- A prueba de errores 3.5- Mirror remoto 3.6- Check final 3.7- El script completo(backup.sh) 4- Invocando el script desde crontab #!/bin/bash bash bits/random hacks

Transcript of Como Hacer Buenos Backups Usando Un Simple Script

Page 1: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 1/14

viernes, 20 de febrero de 2009

De como hacer buenos backupsusando un simple script(o KISSbakcup)

Supongamos un server recién instalado, llevó horas configurarlo,

dejarlo afinado como un violín, pero cuando creemos haber

terminado aún hay como una sensación, algo que no está bien,

pero... que será?

"Puede fallar" decía Tusam, y todos comprobamos la verdad de

estas sabias palabras alguna vez en la vida.

Pero...qué pude fallar?

short answer: "todo puede fallar"

Lo bueno es que muchas de las cosas son reemplazables, mother,

memorias, fuentes, discos se consiguen a buen precio hoy, pero

que hay de las horas de configuración?, los datos acumulados?, los

emails?, las bases de datos?

La posibilidad de que esa información valiosa se pierdan siempre ha

sido un itch to scratch.

-Indice

1- Objetivos

2- Requisitos

3- Desarrollo

3.1- Configuración

3.2- Setup inicial

3.3- Creando el backup

3.4- A prueba de errores

3.5- Mirror remoto

3.6- Check final

3.7- El script completo(backup.sh)

4- Invocando el script desde crontab

#!/bin/bashbash bits/random hacks

Page 2: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 2/14

5- Ejemplo de salida

6- Conclusión

1- Objetivos

Hacer un script de backup que

sea tan simple de usar como poner una linea en cron

permita backup versionado en el tiempo

optimice el espacio de los backups

pueda hacer mirror remoto de los mismos

borre automaticamente los viejos para hacer espacio a los

nuevos

salga limpiamente de los errores que se puedan producir y

garantice la integridad

avise a alguien del error enviandole un detalle del fallo

que mientras funcione bien sea silencioso y pase

desapercibido

2- Requisitos

bash

tar

lftp

3- Desarrollo

Tener un itch to scratch nunca es garantía de que llegará el

scratch, ahí es cuando el cliente exijente aparece y de alguna

manera fuerza y/o financia el scratch:

cliente- muy bueno como quedó todo, ahora tengo

una pregunta, de esto hay backup?

geek- eh... sí, naturalmente, como no va a haber

backup!

Todo comenzó con un simple script para salir del paso, y a medida

que pasaron los años las necesidades de backup se volvieron cada

vez más complejas.

Varios checkpoints en el tiempo, mirror remoto, aviso en caso de

fallos, backups incremental fueron algunas de las exigencias, y el

pequeño script fue creciendo y evolucionando cada vez más.

3.1- Configuración

La primera parte del script está dedicada la configuración, esto es

lo que da al script flexibilidad.

Page 3: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 3/14

Lo primero es elegir el directorio en donde se van a guardar los

backups, la ventaja de esto es que ese directorio puede caer en

un disco diferente al principal, o incluso puede ser una unidad de

red montada via smbfs o nfs por ejemplo.

view plain print ?

01. #!/bin/bash 02. # directorio donde van a parar los backups 03. backup_dir="/backup"

Luego viene la parte de remote mirror de los bakcups, el script usa

ftp para mantener en syncro el directorio de backups local con el

remoto. Si dejamos en blanco estas variables el script realiza solo

el backup en el directorio local.

view plain print ?

01. # datos ftp, si están en blanco el backup es sólo local

02. ftp_host=10.0.0.1 03. ftp_user=backup 04. ftp_pass=******

La siguiente variable nos pide el nombre de un usuario o un email

al cual enviar un aviso en caso de que el script falle en alguno de

sus pasos.

view plain print ?

01. # mail a donde avisar si algo sale mal, puede ser un usuario del sistema

02. mail_for_errors="root"

backup_days representa el numero de días de los cuales vamos a

tener backups, a mayor cantidad de días, más espacio en disco

necesitaremos.

view plain print ?

01. # tiempo en dias que conserva copia de los backups

02. backup_days=15

A continuación configuramos que cosas vamos a incluir y excluir

dentro del bakcup. En un backup completo tradicional incluiremos

el directorio raiz "/" y excluiremos cosas como /tmp,/proc y /sys

entre otros.

Hay que acordarse de excluir cualquier directorio que contenga

mucha información que pueda inflar innecesariamente los backups,

por ejemplo el cache de squid o el fuente de un kernel en /usr/src,

en fin,cosas que no vale la pena tener por duplicado.

Obviamente se excluye el $backup_dir para no crear una

Page 4: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 4/14

recursividad tratando de backupear el propio directorio de

backups.

view plain print ?

01. exclude=$(mktemp) 02. include=$(mktemp) 03. cat > $include <<EOF 04. / 05. EOF 06. cat > $exclude <<EOF 07. /tmp/* 08. /sys/* 09. /proc/* 10. /var/spool/squid/* 11. $backup_dir 12. EOF

Después de esto comienza realmente el script, así que llegamos a

la linea divisoria, si estás buscando una solución Copy and Paste,

podés saltar todo esto y descargar el script completo

3.2- Setup inicial

Voy a explicar la solución paso a paso, en el orden de ejecución.

Para esto me voy a tomar la libertad de explicar las funciones

cuando son llamadas y no en el orden en que aparecen en el script

original.

Comenzamos creando un logfile donde redireccionar la stderr de

los programas que usamos a lo largo del script, para poder recopilar

los errores de los mismos y despues enviarlos por mail.

También creamos un directorio .tar, dentro de nuestro directorio

de bakcups. Este directorio lo usaremos para guardar el archivo

para backups incremental y unos lock que me aseguraran de que el

script pueda recuperarse de un fallo.

view plain print ?

01. # Scripts Begins Here 02. logfile=$(mktemp) 03. inc_dir="${backup_dir}/.tar" 04. inc_file="${inc_dir}/incremental.info" 05. [ -d "$backup_dir" ] || mkdir -p "$backup_dir" 06. [ -d "$inc_dir" ] || mkdir -p "$inc_dir"

El pŕoximo paso es borrar los backups que ya son viejos segun

$backup_days

view plain print ?

01. # borro los backups vencidos 02. find $backup_dir -name "backup-$(hostname)-*" -

ctime +$backup_days -a -type f -exec rm -f {} \;

Page 5: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 5/14

En esta linea hago la primera comprobación de error. Cuando

comienzo a crear un backup completo, creo un archivo .lock, que

se borrará al final si todo sale exitosamente.

Pero si algo falla, entonces el archivo .lock permanece creado hasta

la próxima ejecución del script. Si encuentro ese archivo es porque

algo salío mal y sé que debo hacer nuevamente el backup completo

(full).

view plain print ?

01. # si encuentro .lock es porque fallo el full backup, borro inc_file para que se haga de nuevo

02. [ -f "${inc_file}.lock" -a -f "$inc_file" ] && rm -f "$inc_file"

El script maneja dos tipos de backup, full e incremental.

El backup full se realiza una vez a la semana, y es un backup de tar

autocontenido, que contiene toda la información necesaria para

ser usado y extraido en cualquier lugar.

El backup incremental se realiza a diario, y se usa como referencia

siempre el último backup full. Esto quiere decir que el lunes se

realiza un backup incremental teniendo en cuenta el último backup

full que es el del domingo. Y si quiciera restaurar el sistema al día

lunes debería primero extraer el backup full del domingo y luego

arriba de ese usar el del lunes.

Los backups incrementales son independientes, esto quiere decir

que están siempre hechos contra el último backup full, por lo que

si tengo un backup incremental del viernes y quiero restaurar el

sistema a ese día, entonces sólo necesito el último backup full

(domingo) más el incremental del viernes.

Esto está hecho así para asegurar la efectividad de los backups, ya

que si para poder recuperar el viernes dependiera de que el lunes,

martes, miércoles y jueves se hayan realizado con éxito estoy

siendo muy optimista por default.

Cada backup tiene su nombre, que incluye el hostname, indica si

es full o incremental y la fecha a la cual corresponde. En el caso de

los incrementales se usa unicamente el día de la semana para que

se vayan pisando con los anteriores y así tener sólo la última

semana en formato incremental.

view plain print ?

01. #setup full or incremental 02. if [ $(date +%u) -eq 7 -o ! -f "$inc_file" ];then 03. #backup-full 04. backup_name="${backup_dir}/backup-$(hostname)-

full-$(date +%Y-%m-%d).tar.gz" 05. #borro inc_file para que el backup sea full 06. [ -f "$inc_file" ] && rm -f "$inc_file" 07. touch "${inc_file}.lock"

Page 6: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 6/14

08. else 09. #backup-inc 10. backup_name="${backup_dir}/backup-$(hostname)-

inc-$(date +%A).tar.gz" 11. cp $inc_file ${inc_file}.temp 12. inc_file=${inc_file}.temp 13. fi

3.3- Creando el backup

Finalmente una vez que todo está listo, hago el backup

view plain print ?

01. #finally, do the backup 02. tarme "$inc_file" "$backup_name"

tarme es una función, veamosla en detalle, lo que hace es invocar

a tar con ciertos parámetros especiales, como que archivos incluir

y excluir del backup, que preserve owners y permisos o que envíe

stderr a logfile.

view plain print ?

01. tarme() { 02. local inc_file=$1 file=$2 03. tar --listed-incremental="$inc_file" \ 04. --files-from="$include" \ 05. --exclude-from="$exclude" \ 06. --ignore-failed-read \ 07. --absolute-names \ 08. -

zpcf "$file" 2>$logfile || do_exit "tar" $? $file

09. return 0 10. }

3.4- A prueba de errores

Como se puede ver al final de la invocación de tar, hay un "||

do_exit ..."

do_exit es otra función, que la vamos a utlizar en caso de que algo

salga mal, en bash cuando un comando devuelve 0 es que todo fue

bien en su ejecución, en cambio si el valor es != de cero es que

algo salió mal. Al poner "|| do_exit" me estoy asegurando que si

algo sale mal la función do_exit se ejecute.

do_exit va a ser usado por tar pero también por otros comandos

que fallen, la idea es que haga un clenaup si el backup quedó

inconsistente y que envíe un mail al administrador avisando que

algo salío mal.

view plain print ?

01. do_exit() { 02. local app=$1 exit_status=$2 file=$3

Page 7: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 7/14

03. case $app in 04. tar) #exit status 1 en tar no es un error fatal:

05. #If tar was given ‘--create’, ‘--

append’ or ‘--update’ option, 06. #this exit code means that some files were c

hanged while being 07. #archived and so the resulting archive does

not contain the 08. #exact copy of the file set. 09. [ $exit_status -eq 1 ] && return 10. #borro el backup que fallo xq esta incomplet

o 11. [ -n "$file" -a -f "$file" ] && rm -

f "$file" 12. ;; 13. esac 14. cat $logfile | mail -

s "Backup error host:$(hostname) app:$app exit_status:$exit_status file:$file" $mail_for_errors

15. exit 1 16. }

3.5- Mirror remoto

Luego de que tar corrio exitosamente, hacemos el upload remoto

si es que corresponde

view plain print ?

01. [ -n "$ftp_host" ] && uploadme "$backup_name"

uploadme es otra función, lo que hace es hacer un mirror del

directorio local de backups contra un ftp remoto, en este sentido

el comando mirror de lftp es de gran ayuda.

Lo bueno de esto es que la sincronía puede fallar un día, pero en

cuanto el script vuelva a correr el directorio local y remoto de

backups terminaran perfectamente sincronizados.

view plain print ?

01. uploadme() { 02. local file=$1 03. lftp -

c "open ftp://$ftp_user:$ftp_pass@$ftp_host;mirror -R --delete-first $backup_dir (hostname)" 2>>$logfile || do_exit "lftp" $? $file

04. return 0 05. }

3.6- Check final

Una vez subido el backup, entonces estamos en condices de borrar

el .lock file, si es que lo habiamos creado (sólo se usa para los full

backups)

view plain print ?

Page 8: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 8/14

01. # si todo fue bien borro el .lock 02. [ -f "${inc_file}.lock" ] && rm -

f "${inc_file}.lock"

3.7- El script completo(backup.sh)

Descargar el script completo: backup.sh

4- Invocando el script desde crontab

Generalmente coloco el script en /usr/local/bin/backu.sh y luego

agrego esta linea a alguan crontab, puede ser la de root(crontab -

e) o en /etc/cron.d/ en alguan crontab personal.

La linea de cron es simplemente para ejecutarlo una vez al día

preferentemente en un horario de poco impacto para el servidor,

como son las horas de la madrugada

view plain print ?

01. 0 2 * * * root /usr/local/bin/backup.sh

5- Ejemplo de salida

Pego la salida de ls sobre un directorio de bakcups, en donde se

han acumlado tres semanas.

Como se puede observar hay una gran diferencia de tamaño entre

un backup full y uno incremental. También se ve como los

incrementales solo cubren la primer semana y luego quedan sólo

full 3 semanas hacia atras.

view plain print ?

01. -rw-r--r-- 1 root root 1.4G 2009-04-19 03:16 backup-sequre-0001-full-2009-04-19.tar.gz

02. -rw-r--r-- 1 root root 1.3G 2009-04-26 03:15 backup-sequre-0001-full-2009-04-26.tar.gz

03. -rw-r--r-- 1 root root 16M 2009-04-27 03:02 backup-sequre-0001-inc-Monday.tar.gz

04. -rw-r--r-- 1 root root 16M 2009-04-28 03:02 backup-sequre-0001-inc-Tuesday.tar.gz

05. -rw-r--r-- 1 root root 30M 2009-04-29 03:02 backup-sequre-0001-inc-Wednesday.tar.gz

06. -rw-r--r-- 1 root root 30M 2009-04-30 03:02 backup-sequre-0001-inc-Thursday.tar.gz

07. -rw-r--r-- 1 root root 30M 2009-05-01 03:02 backup-sequre-0001-inc-Friday.tar.gz

08. -rw-r--r-- 1 root root 50M 2009-05-02 03:02 backup-sequre-0001-inc-Saturday.tar.gz

09. -rw-r--r-- 1 root root 1.3G 2009-05-03 03:16 backup-sequre-0001-full-2009-05-03.tar.gz

6- Conclusión

Tener backups es garantía de buen sueño para un sys-admin y, es

además, una marca de calidad en lo que a infraestructura respecta.

Page 9: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 9/14

Si bien hay soluciones de backup muy interesantes como bacula o

backuppc, hay escenarios en donde no se justifica hacer

semejante despliegue de configuración e infraestructura.

Escenarios donde lo único que necesitamos es tener una copia

fresca y con archivo de un servidor, en donde dedicar más de 5

miutos de setup sería perder tiempo y dinero.

Este script hace que tener backups sea algo sencillo de

implementar, sin descuidar la calidad de los resultados, así que ya

no hay más excusas para tener un sólo server sin backup.

Good luck and good backups :)

Etiquetas: backup , incremental , linux , mirror , script , tar

Publicadas por luciano This entry was posted on viernes, 20 de febrero de

2009 a la/s 12:38 You can skip to the end and leave a response.

13 comentarios:

Alejandro L dijo... 14 de junio de 2009 19:28

Hola Amigo.. muy bune post.. voy aimplementarlo te cuento

Modemhead dijo... 23 de junio de 2009 12:36

Muy bueno! Es mas de lo que estaba buscando:O

Segui así con el blog q esta muy groso!

saludos

Eduard4D dijo... 6 de julio de 2009 07:32

Buenas , primero de todo, muchas gracias, eraexactamente lo que buscaba, pero me aguarda

Page 10: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 10/14

una duda, la primera vez q he ejecutado elscript, este me hace uno completo. SI quiero qvaya haciendome incrementales como debollamar al script?

GraciasEduard

luciano dijo... 8 de julio de 2009 10:35

@Eduard4D la primera vez siempre hace unbackup full porque es imposible hacerincrementales si no hay uno completo dereferencia.El script se llama siempre igual, sin ningunparametro especial. La inteligencia internadel mismo hará backups incrementales hastallegar al día 7 de la semana(domingo) donderealizara un nuevo backup completo y asíempezar de nuevo.

kbs dijo... 20 de julio de 2009 16:27

muy buen script amigo

una pregunta, el backup incremental se basasolamente en si el archivo existe o no? se dacuenta si yo modifico el archivo para meterloen el nuevo backup?

Por ejemplo, yo tengo un directorio con elarchivo "hola" está vacio, el dia 1 hago unbackup full, el segundo dia yo escribo algo enel archivo "hola", el backup incremental se dacuenta que el archivo es diferente?

Ing. Sabas Medina Morales dijo... 13 de diciembre de 2011 14:19

Excelente el script. Me gustaria saber que

Page 11: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 11/14

variaciones debo hacerle si quiero hacerbackups de los switches cisco de la empresadonde trabajo. De antemano gracias

luciano dijo... 13 de diciembre de 2011 17:05

@SabasEs muy distinto hacer backups de switchs orouters ya que cada uno tendrá una maneradistinta de acceder al dump. Para ciscoespecificamente google siempre te dara unamano

Anónimo dijo... 22 de junio de 2012 00:28

buenas noches. la verdad me gusto el codigopreo tengo 2 pregunta :

una es que no me envia notificaciones a micorreo}y la otra es que quisiera saver si sepuede reducir la comprencion mas

Javier Lleo Tomás dijo... 28 de septiembre de 2012 06:11

Estaba buscando algo sencillo y efectivo, estescript encaja a la perfección.

Muchas gracias por el articulo y lasexplicaciones, muy bueno.

un saludo.

Daniel Diaz dijo... 29 de noviembre de 2012 21:15

Page 12: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 12/14

Muy bueno lo implemente y me va demaravillas.Ahora soy muy limitado en linux, mi duda es.Como restauro uno de estos backups??ejemplo, tengo como el ls que muestras, estoyen el dia viernes y quiero restaurar el backupdel dia miercoles, como hago eso?Saludos a la distancia!

luciano dijo... 29 de noviembre de 2012 22:03

Para resutaurar usas el comando tar.Siempre debes restaurar primero uno de losbackup full, y luego basta con un únicoincremental del día al que quieras llegar. Elcomando sería algo asítar --numeric-owner -zxpvf backup.tar.gz

Daniel Diaz dijo... 4 de diciembre de 2012 17:50

sigo sin entender perdon, podrias ser masgrafico? tengo estos archivos: backup-mdh-full-2012-12-02.tar.gzbackup-mdh-inc-sábado.tar.gzbackup-mdh-inc-lunes.tar.gzbackup-mdh-inc-martes.tar.gzbackup-mdh-inc-miercoles.tar.gz

Supongamos que estoy a viernes y quierorestaurar el incremental del dia martes. Comohago esta operacion?Gracias y disculpa las molestias.

Anónimo dijo... 11 de marzo de 2013 18:55

hola como puedo hacer un scrips linux, que mepermita copiar el contenido de varios archivoslogs. y ubicarlos en uno solo....automaticamente cada 5 minutos ......

Page 14: Como Hacer Buenos Backups Usando Un Simple Script

06/09/13 #!/bin/bash: De como hacer buenos backups usando un simple script(o KISS bakcup)

bourneagainshell.blogspot.mx/2009/02/to-backup.html 14/14

multipath (1)

script (1)

tar (1)