Categories

Backup pentru fisiere si directoare folosind comenzi shell.

Backup pentru fisiere si directoare folosind comenzi BASH (a.k.a poor man’s backup tool) presupune crearea unei copii de siguranta pentru anumite fisiere si directoare folosind doar comenzi si unelte disponibile in linia de comanda a oricarui sistem Linux/Unix.

In acest tutorial am folosit un sistem cu Fedora 14 pentru care vreau sa fac copii de siguranta a directoarelor /etc, /var si /home . De asemenea voi folosi o strategie de backup relativ simpla care presupune crearea unui backup complet o data pe saptamina si cite un backup incremental in restul zilelor din saptamina.

Pentru inceput am definit o structura de directoare care sa ma ajute sa pastrez toate lucrurile intr-o ordine cit de cit decenta. Aceasta structura arata asa:

/backups                      <— directorul radacina, trebuie sa aiba suficient spatiu liber ca sa incapa toate datele pe care vreau sa le pastrez. Poate sa fie un disc suplimentar intern sau extern, un sistem de fiesiere accesibil prin retea, sau orice dispozitiv de stocare care are suport si care poate fi montat in /backups.
/backups/full                 <— va contine fiecare arhiva rezultata din executia cu succes a unui backup complet (full backup)
/backups/incr                <— va contine fiecare arhiva rezultata din executia cu succes a unui backup incremental
/backups/scrips             <— va contine scripturile BASH pentru fiecare tip de backup (fiecare job)
/backups/jobs_output    <— va contine output-ul generat de fiecare job executat

Aceasta structura de directoare am creat-o cu urmatoarea comanda:

mkdir -p /backups/full /backups/incr /backups/scripts /backups/jobs_output

Partea de initializare a procesului se rezuma la crearea unui fisier referinta care va avea ca data a ultimei modificari data la care s-a facut ultimul backup cu succes. In caz particular, atit pentru prima iteratie cit si inainte de fiecare backup complet, am sa initializez data de la care vreau sa includ fisiere intr-un backup complet (full), ca fiind 1 ianuarie 1970, ora 0:00 UTC (1970-01-01 00:00:00 UTC = Unix Epoch) fiindca stiu sigur ca nu am fisiere care au fost create/modificate inainte de aceasta data.

touch --date="1970-01-01 00:00:00 UTC" /backups/.backup_reference

Deoarece, prin definitie, un backup incremental contine toate fisierele care s-au modificat de la ultimul backup realizat cu succes, toate comenzile pentru selectia fisierelor care vor fi incluse intr-un backup incremental vor folosi data ultimei modificari a fisierului refereinta pe post de criteriu de selectie a fisierelor care sa fie incluse in backup-urile incrementale.

Pentru a realiza un backup complet (full backup), rulez periodic urmatoarele comenzi:

touch --date="1970-01-01 00:00:00 UTC" /backups/.backup_reference

find /etc /var /home -newer /backups/.backup_reference > /backups/.files_to_archive

touch /backups/.backup_reference

tar -zcvf /backups/full/full_backup-$(date +%F).tar.gz --files-from /backups/.files_to_archive

Prima comanda “touch” seteaza data la care am terminat cu success ultimul backup. Fiindca intr-un backup complet vrau sa includ toate fisierele, aceasta data trebuie sa fie suficient de departe in trecut incit nici unul din fisierele importante pentru mine sa nu se fi modificat mai devreme decit data ultimei modificari a fisierului referinta.

Comanda “find” creaza o lista cu toate fisierele si directoarele din /etc /var si /home care au fost modificate mai recent decit data ultimei modificari a fisierului referinta salvind aceasta lista in fisierul .files_to_archive.

A doua comanda “touch” actualizeaza data ultimei modificari a fisierului referinta cu data curenta cu scopul de a putea fi folosita ulterior de un backup incremental pentru selectia fisierelor modificate dupa ultima operatie de backup.

Comanda “tar” creaza o arhiva tarball, comprimata cu gzip, care va contine toate fisierele a caror cale completa si nume sint listate in fisierul .files_to_archive.

In mod analog, pentru a realiza un backup incremental rulez periodic urmatoarele comenzi:

find /etc /var /home -newer /backups/.backup_reference > /backups/.files_to_archive

touch /backups/.backup_reference

tar -zcvf /backups/incr/incr_backup-$(date +%F).tar.gz --files-from /backups/.files_to_archive

Totul in script-uri shell:

Continutul fisierului /backups/scripts/incr_job.sh care va fi executat de fiecare data cind doresc sa fac un backup incremental:

#!/bin/bash

echo "$(/bin/date +"%Y-%m-%d %H:%M:%S") Staring incremental backup..."
/bin/find /etc /var /home -newer /backups/.backup_reference > /backups/.files_to_archive
/bin/touch /backups/.backup_reference
/bin/tar -zcvf /backups/incr/incr_backup-$(date +%F).tar.gz --files-from /backups/.files_to_archive
echo "$(/bin/date +"%Y-%m-%d %H:%M:%S") Finished incremental backup..."

Continutul fisierului /backups/scripts/full_job.sh care va fi executat de fiecare data cind doresc sa fac un backup complet:

#!/bin/bash

b_file=full_backup-$(date +%F).tar.gz

echo "$(/bin/date +"%Y-%m-%d %H:%M:%S") Staring full backup..."
/bin/touch --date="1970-01-01 00:00:00 UTC" /backups/.backup_reference
/bin/find /etc /home /var -newer /backups/.backup_reference > /backups/.files_to_archive
/bin/touch /backups/.backup_reference
/bin/tar -zcvf /backups/full/$b_file --files-from /backups/.files_to_archive
echo "$(/bin/date +"%Y-%m-%d %H:%M:%S") Finished full  backup..."

echo "$(/bin/date +"%Y-%m-%d %H:%M:%S") Cleaning up older incremental backups..."
/bin/find /backups/incr/ -type f ! -newer /backups/full/$b_file -exec rm -fv {} \;

echo "$(/bin/date +"%Y-%m-%d %H:%M:%S") Cleaning up full backups older than 90 days..."
/bin/find /backups/full/ -type f -mtime +90 -exec rm -fv {} \;

echo "$(/bin/date +"%Y-%m-%d %H:%M:%S") Done."

In acest fisier am adaugat doua comenzi “find” suplimentare care sint responsabile cu gasirea si stergerea arhivelor tar.gz cu backup-uri incrementale care sunt mai vechi decit ultimul backup complet si de asemenea gasirea si stergerea tuturor arhivelor tar.gz cu backup-uri complete care nu au fost modificate de cel putin 90 de zile. In acest fel ma asigur ca spatiul ocupat de arhivele cu backup-uri este reciclat/eliberat dupa o anumita perioada de retentie a fisierelor arhivate putind fi astfel reutilizat.

Pentru a implementa strategia de backup la care m-am decis, este necesar ca cele doua scripturi (backup jobs) sa fie rulate periodic intr-un ciclu saptaminal bine definit ceea ce se poate implementa foarte usor cu ajutorul cron.

Configurarea daemon-ului cron pentru automatizarea operatiilor repetitive am facut-o astfel:

0 1 * * 1-6 /backups/scrips/incr_job.sh >> /backups/jobs_output/inc_backup-$(/bin/date +%F).out 2>&1
0 1 * * 0 /backups/scrips/full_job.sh >> /backups/jobs_output/full_backup-$(/bin/date +%F).out 2>&1

Prima linie executa un backup incremental la ora 1:00 de luni pina simbata, a doua linie executa un backup complet la ora 1:00 in fiecare duminica. Pentru ambele comenzi am redirectat output-ul inspre un fisier text care are ca parte din numele sau data din ziua in care a fost executata astfel incit verificarea functionaraii corecte sa poata fi efectuata prin simpla consultare a acestui fisier jurnal.

 

2 comments to Backup pentru fisiere si directoare folosind comenzi shell.

Leave a Reply to cralin

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>