Säkerhetskopiering med DAR

Backup servern

På backup servern bör det skapas en användare som sha ha bra med plats i sitt hem för att lagra backuperna.

groupadd backup; useradd -m -d /home/backup -g backup backup
mkdir /home/backup/_scripts

Jag avslöjar inte hur lite utrymme jag har på min labbburk för den här guiden.. :)
Inne i /home/backup skapar jag direkt underkatalogen _scripts där jag kommer lägga backupscripten (för dar och ev. för MySQL).

Backup script för lokal backup

Om servern ska användas för 'lokal' backup, dvs det kommer finnas på ett eller annat sätt (NFS, Samba) uppmountad data att ta backup på så behövs tre script installeras på den. Jag brukar lägga backup-scripten i /home/backup/_scripts (eller i _scripts i det som står som 'LOCAL_DIR' i scripten)

I alla script (nära början) finns sökvägen för vart backupfilerna ska läggas:
LOCAL_DIR="/home/backup/$3"

Inne i den katalogen skapas det ytterligare en underkatalog (för server, ex 'webserver'), och en underkatalog i den för den månad backupen togs (ex '2007-05').

En komplett struktur för 'webserver' och 'mailserver' kan komma att se ut så här (efter 3 månader):

/home/backup --- webserver --- 2007-03
              |             |- 2007-04
              |             |- 2007-05
              |
              |- mailserver --- 2007-03
                             |- 2007-04
                             |- 2007-05

Inne i 'månadskatalogerna' läggs alla backupfiler, och deras namn skapas med hjälp av angivet 'basename' (som på nåt smart sätt definierar vad backupen innehåller, ex. 'home', 'root', 'system'), datumet och tiden då backupen togs, och backuptyp (full, incr eller diff). Några kompletta filnamn kan vara:

home_20070501_0012_full.1.dar
root_20070501_0005_full.1.dar
system_20070501_0111_full.1.dar

home_20070502_0005_diff.1.dar
root_20070502_0005_diff.1.dar
system_20070502_0011_diff.1.dar

...

home_20070510_0011_incr.1.dar
root_20070510_0005_incr.1.dar
system_20070510_0027_incr.1.dar

I exemplet ovan tas full backup den 1:a varje månad, en diff görs varje dag, och en inkrementell backup görs den 10:e, 19:e och 28:e varje månad.

dar_local_full_backup.sh

Tar en full backup på de filer som ges som parameter till scriptet. För att ta en full backup av den lokala maskinens (backupserverns) /home

/home/backup/_scripts/dar_local_full_backup.sh "-R /home" x backupserver home

Parametrarna talar om för scriptet att 'root' för backupen ska sättas till /home (-R /home), och att filerna ska lagras i månadskatalogen i backupserver i /home/backup. Backupfilernas namn kommer att börja på 'home'. För en liknande backup på hela systemet utom /home används kommandot:

/home/backup/_scripts/dar_local_full_backup.sh "-R / -P home" x backupserver system

För att hindra att det tas backup på en viss sökväg så används parametern -P dirname, i det här fallet -P /home.

#!/bin/sh
# dar_local_full_backup.sh <darextra> <remotelogin> <remotedir> <basename>
# darextra = relative path from / to backup, directories to ignore... (-P <dir>)
if [ $# -ne 4 ]; then
  echo 1>&2 "Usage: $0 <darextra> x <remotedir> <basename>"
  exit 127
fi

# some configuration
DATE_Y_M=`date +%Y-%m`

# directory for local storage (catalogs and pointers to last backup)
LOCAL_DIR="/home/backup/$3"

# directory for backup storage ($3 = remotedir, append year and month)
BACKUP_DIR="${LOCAL_DIR}/${DATE_Y_M}"
mkdir -p ${BACKUP_DIR}

# -- step 1 create backup
cd ${BACKUP_DIR}
DATE=`date +%Y%m%d_%H%M`
FILE="${4}_${DATE}_full"
DARCMD="/usr/local/bin/dar -z7 -c ${FILE} $1"
sh -c "$DARCMD"

# -- step 2 create backup catalog
CATCMD="/usr/local/bin/dar -w -A $FILE -C ${FILE}_CAT -z7"
sh -c "$CATCMD"

# -- step 3 store name of last full backup
cd ${LOCAL_DIR}
if [ -f ${DATE_Y_M}/${FILE}_CAT.1.dar ]; then
  echo >${4}_latest_full ${DATE_Y_M}/${FILE}

  # -- step 4 remove pointers to last incremental and diff backups
  rm ${4}_latest_incr
  rm ${4}_latest_diff
fi

dar_local_incr_backup.sh

Används på samma sätt som dar_local_full_backup.sh, men tar endast backup på filer som ändrats sen den senaste fullständiga backup gjordes.

#!/bin/sh
# dar_local_incr_backup.sh <darextra> <remotelogin> <remotedir> <basename>
# darextra = relative path from / to backup, directories to ignore... (-P <dir>)
if [ $# -ne 4 ]; then
  echo 1>&2 "Usage: $0 <darextra> x <remotedir> <basename>"
  exit 127
fi

# some configuration
DATE_Y_M=`date +%Y-%m`

# directory for local storage (catalogs and pointers to last backup)
LOCAL_DIR="/home/backup/$3"

# directory for backup storage ($3 = remotedir, append year and month)
BACKUP_DIR="${LOCAL_DIR}/${DATE_Y_M}"
mkdir -p ${BACKUP_DIR}

cd ${LOCAL_DIR}
# get name of last full backup..
if [ -f ${4}_latest_full ]; then
  PREV_BACKUP=`cat ${4}_latest_full`
fi

# check that the backup file exists
if [ -f ${PREV_BACKUP}_CAT.1.dar ]; then
  echo $PREV_BACKUP
else
  echo "Can't do an incremental backup if no previous full backup have been made"
  exit 127
fi

# -- step 1 create backup
cd ${BACKUP_DIR}
DATE=`date +%Y%m%d_%H%M`
FILE="${4}_${DATE}_incr"
DARCMD="/usr/local/bin/dar -A ${LOCAL_DIR}/${PREV_BACKUP}_CAT -z7 -c ${FILE} $1"
echo $DARCMD
sh -c "$DARCMD"

# -- step 2 create backup catalog
CATCMD="/usr/local/bin/dar -w -A $FILE -C ${FILE}_CAT -z7"
echo $CATCMD
sh -c "$CATCMD"

# -- step 3 store name of last incr backup
cd ${LOCAL_DIR}
if [ -f ${DATE_Y_M}/${FILE}_CAT.1.dar ]; then
  echo >${4}_latest_incr ${DATE_Y_M}/${FILE}

  # -- step 4 remove pointers to last diff backups
  rm ${4}_latest_diff
fi

dar_local_diff_backup.sh

Används på samma sätt som dar_local_full_backup.sh, men tar endast backup på filer som ändrats sen den senaste backupen togs (fullständig, inkrementell eller differentiell).

#!/bin/sh
# dar_local_incr_backup.sh <darextra> <remotelogin> <remotedir> <basename>
# darextra = relative path from / to backup, directories to ignore... (-P <dir>)
if [ $# -ne 4 ]; then
  echo 1>&2 "Usage: $0 <darextra> x <remotedir> <basename>"
  exit 127
fi

# some configuration
DATE_Y_M=`date +%Y-%m`

# directory for local storage (catalogs and pointers to last backup)
LOCAL_DIR="/home/backup/$3"

# directory for backup storage ($3 = remotedir, append year and month)
BACKUP_DIR="${LOCAL_DIR}/${DATE_Y_M}"
mkdir -p ${BACKUP_DIR}

cd ${LOCAL_DIR}
# get name of last full backup..
if [ -f ${4}_latest_full ]; then
  PREV_BACKUP=`cat ${4}_latest_full`
fi

# if a incremental has been made, use it in place of full backup
if [ -f ${4}_latest_incr ]; then
  PREV_BACKUP=`cat ${4}_latest_incr`
fi

# and use last diff in place of incremental if a diff has been made since last incremental
if [ -f ${4}_latest_diff ]; then
  PREV_BACKUP=`cat ${4}_latest_diff`
fi

# check that the backup file exists
if [ -f ${PREV_BACKUP}_CAT.1.dar ]; then
  echo $PREV_BACKUP
else
  echo "Can't do a diff backup if no previous backup have been made"
  exit 127
fi

# -- step 1 create backup
cd ${BACKUP_DIR}
DATE=`date +%Y%m%d_%H%M`
FILE="${4}_${DATE}_diff"
DARCMD="/usr/local/bin/dar -A ${LOCAL_DIR}/${PREV_BACKUP}_CAT -z7 -c ${FILE} $1"
echo $DARCMD
sh -c "$DARCMD"

# -- step 2 create backup catalog
CATCMD="/usr/local/bin/dar -w -A $FILE -C ${FILE}_CAT -z7"
echo $CATCMD
sh -c "$CATCMD"

# -- step 3 store name of last diff backup
cd ${LOCAL_DIR}
if [ -f ${DATE_Y_M}/${FILE}_CAT.1.dar ]; then
  echo >${4}_latest_diff ${DATE_Y_M}/${FILE}
fi

När du kopierat in ovanstående script i /home/backup/_scripts, måste du först markera dom som körbara, sen ska allt vara klart för att kunna ta backup lokalt.

chmod 700 /home/backup/_scripts/*sh

Provkörning och fler script

Provkör dar_local_full

/home/backup/_scripts/dar_local_full_backup.sh "-R /etc" x backupserver etc

Du bör få ett resultat liknande:

Reading config file: /etc/darrc


 --------------------------------------------
 235 inode(s) saved
 with 0 hard link(s) recorded
 0 inode(s) changed at the moment of the backup
 0 inode(s) not saved (no inode/file change)
 0 inode(s) failed to save (filesystem error)
 0 inode(s) ignored (excluded by filters)
 0 inode(s) recorded as deleted from reference backup
 --------------------------------------------
 Total number of inode considered: 235
 --------------------------------------------
Reading config file: /etc/darrc
rm: etc_latest_incr: No such file or directory
rm: etc_latest_diff: No such file or directory

Om allt gick bra bör du ha tre filer inne i den automatiskt skapade katalogen /home/backup/backupserver:

2007-05/etc_20070525_1103_full.1.dar
2007-05/etc_20070525_1103_full_CAT.1.dar
etc_latest_full

I det här fallet gjorde jag backupen 25:e maj 2007 (20070525), och då skapades också månadskatalogen '2007-05' automatiskt.
Filen etc_latest_full innehåller filnamnet på den senaste fullständiga backup som togs (diff och incr använder den filen för att veta vad som är förändrat).

Provkör dar_local_diff minst en minut senare

Ändra gärna (eller lägg till) nån fil på platsen du tar backup på, för att vara säker på att något har hänt sen sist.

/home/backup/_scripts/dar_local_diff_backup.sh "-R /etc" x backupserver etc

Du bör få ett resultat liknande:

2007-05/etc_20070525_1103_full
/usr/local/bin/dar -A /home/backup/backupserver/2007-05/etc_20070525_1103_full_CAT -z7 -c etc_20070525_2351_diff -R /etc
Reading config file: /etc/darrc


 --------------------------------------------
 2 inode(s) saved
 with 0 hard link(s) recorded
 0 inode(s) changed at the moment of the backup
 233 inode(s) not saved (no inode/file change)
 0 inode(s) failed to save (filesystem error)
 0 inode(s) ignored (excluded by filters)
 0 inode(s) recorded as deleted from reference backup
 --------------------------------------------
 Total number of inode considered: 235
 --------------------------------------------
/usr/local/bin/dar -w -A etc_20070525_2351_diff -C etc_20070525_2351_diff_CAT -z7
Reading config file: /etc/darrc

2 inode(s) saved betyder att det är två filer som ändrats sen den senaste backupen togs. I mitt fall med labbservern så är det /etc/resolv.conf och en backup av den som ändrats (eller fått uppdaterad ändringstid, men är oändrade)

Det går att lista filerna i backupen med hjälp av dar kommandot:

# dar -as -l /home/backup/backupserver/2007-05/etc_20070525_2351_diff
Reading config file: /etc/darrc
[data ][ EA  ][compr] | permission | user  | group | size  |          date                 |    filename
----------------------+------------+-------+-------+-------+-------------------------------+------------
[Saved]       [     ]   -rw-r--r--   root       wheel   63      Fri May 25 12:01:09 2007        resolv.conf
[Saved]       [     ]   -rw-r--r--   root       wheel   63      Fri May 25 12:01:09 2007        resolv.conf.save

Parametern -as anger att man bara vill få en lista över de filer som verkligen finns sparade i backupen.

Ändra eller lägg till nån fil igen och kör därefter dar_local_diff en gång till på samma sätt som tidigare (jag visar inget resultat nu).

Nu bör du ha en full backup, och två differentiella liggandes i din 'månadskatalog' (om du inte råkade passera ett månadsskifte mitt i testerna, men det fungerar lika bra ändå). Jag har på min labbdator i /home/backup/backupserver nu:

2007-05/etc_20070525_1103_full.1.dar
2007-05/etc_20070525_1103_full_CAT.1.dar
2007-05/etc_20070525_2351_diff.1.dar
2007-05/etc_20070525_2351_diff_CAT.1.dar
2007-05/etc_20070526_0008_diff.1.dar
2007-05/etc_20070526_0008_diff_CAT.1.dar
etc_latest_full
etc_latest_diff

Första backupen som togs var en fullständig. Därefter togs det en differentiell backup (de filer som ändrats sen senaste backupen, som råkade vara 'full'), och sist togs det en till differentiell backup (ändringar sen senaste igen, men denna gång var det den första 'diffen' som var den senaste backupen.

För att återskapa fram tills den sista backupen behövs nu alla tre backuperna. För att göra det enklare att återskapa data kan man göra en inkrementell backup, som sparar ner skillnaden sen den senaste 'fulla' backupen (testa):

/home/backup/_scripts/dar_local_incr_backup.sh "-R /etc" x backupserver etc

Tar du återigen en diff, så blir det som vanligt ändringarna som gjorts sen den senaste backupen som sparas. I detta fallet den inkrementella. Fan, här verkar det behövas en sida 0 med info om vad en backup är för nåt...

Vill du göra en total återställning, så är det full + (senaste) incr + de diffar som gjorts efter den senaste inkr som behövs.

Fler script gör backupen enklare

Oftast vill man ta backup på mer än en katalog, gärna automatiskt, och då kommer några enklare script till användning. Eftersom man med säkerhet inte vet hur länge backupen av en katalog kommer att ta, så är det säkrast att köra dessa i följd, och det med hjälp av ett mycket enkelt shell-script.
Principen är bara att bunta ihop körningen av ovanstående script, så att dessa går att köra i följd med bara ett enkelt kommando.

Anta att vi vill ta backup på följande kataloger:

/etc
/var
/home
hela systemet utom /etc /var och /home

Vi börjar i 'fel ände' med scriptet för en 'diff' backup (de andra scripten är lite mer avancerade).

Normalt skulle man från shell-prompten kunna köra

/home/backup/_scripts/dar_local_diff_backup.sh "-R /etc" x backupserver etc
/home/backup/_scripts/dar_local_diff_backup.sh "-R /usr" x backupserver usr
/home/backup/_scripts/dar_local_diff_backup.sh "-R /home" x backupserver home
/home/backup/_scripts/dar_local_diff_backup.sh "-R / -P home -P usr -P etc" x backupserver system
och väntat mellan körningen av varje backup för att inte belasta filsystem och servern i onödan.

Detta är också precis det som all_local_diff.sh innehåller (förutom första raden som innhåller kommandot som behövs för att köra scriptet):

all_local_diff.sh

#!/bin/sh
/home/backup/_scripts/dar_local_diff_backup.sh "-R /etc" x backupserver etc
/home/backup/_scripts/dar_local_diff_backup.sh "-R /usr" x backupserver usr
/home/backup/_scripts/dar_local_diff_backup.sh "-R /home" x backupserver home
/home/backup/_scripts/dar_local_diff_backup.sh "-R / -P home -P usr -P etc" x backupserver system

Det sista kommandot i scriptet gör backup på allt utom /home, /usr och /etc (som togs om hand först).

De andra scripten är ungefär likadana, med skillnaden att innan 'incr' resp 'full' så tas det en 'diff' utifall man på ett enkelt sätt vill kunna återställa filer som modifierats sen den förra backupen.

all_local_incr.sh

#!/bin/sh
/home/backup/_scripts/dar_local_diff_backup.sh "-R /etc" x backupserver etc
/home/backup/_scripts/dar_local_incr_backup.sh "-R /etc" x backupserver etc
/home/backup/_scripts/dar_local_diff_backup.sh "-R /usr" x backupserver usr
/home/backup/_scripts/dar_local_incr_backup.sh "-R /usr" x backupserver usr
/home/backup/_scripts/dar_local_diff_backup.sh "-R /home" x backupserver home
/home/backup/_scripts/dar_local_incr_backup.sh "-R /home" x backupserver home
/home/backup/_scripts/dar_local_diff_backup.sh "-R / -P home -P usr -P etc" x backupserver system
/home/backup/_scripts/dar_local_incr_backup.sh "-R / -P home -P usr -P etc" x backupserver system

all_local_full.sh

#!/bin/sh
/home/backup/_scripts/dar_local_diff_backup.sh "-R /etc" x backupserver etc
/home/backup/_scripts/dar_local_full_backup.sh "-R /etc" x backupserver etc
/home/backup/_scripts/dar_local_diff_backup.sh "-R /usr" x backupserver usr
/home/backup/_scripts/dar_local_full_backup.sh "-R /usr" x backupserver usr
/home/backup/_scripts/dar_local_diff_backup.sh "-R /home" x backupserver home
/home/backup/_scripts/dar_local_full_backup.sh "-R /home" x backupserver home
/home/backup/_scripts/dar_local_diff_backup.sh "-R / -P home -P usr -P etc" x backupserver system
/home/backup/_scripts/dar_local_full_backup.sh "-R / -P home -P usr -P etc" x backupserver system

Att göra en 'diff' före en 'incr' eller 'full' är mest praktiskt på större mängder data, men används här på allt bara för att visa hur det fungerar. Är det lite data i backupen är det lika enkelt att återställa från den 'incr' eller 'full' backupen.

Arkiv med serverscript

Du kan ladda ner ett arkiv med alla script för servern här:
http://www.bsd-guide.net/dar-backup/files/dar_scripts/dar_server_scripts.tgz
Och som vanligt får du lite klipp-och-klistra-fusk.. :)
mkdir -p /home/backup/_scripts
cd /home/backup/_scripts
wget http://www.bsd-guide.net/dar-backup/files/dar_scripts/dar_server_scripts.tgz
tar xfz dar_server_scripts.tgz
chmod 700 *sh
rm dar_server_scripts.tgz

Inte riktigt klar med guiden än