Teoria Bash 03: Còpies de seguretat amb tar

1. Introducció a les còpies de seguretat

Per què fer backups?

Estratègia 3-2-1

Una bona estratègia de backup segueix la regla 3-2-1:

2. Tipus de còpies de seguretat

Backup Complet (Full)

Copia tots els fitxers i directoris.

Avantatges:

Desavantatges:

# Exemple de backup complet
tar -czf backup_complet_20240108.tar.gz /home/usuari/documents

Backup Incremental

Copia només els fitxers modificats des de l'últim backup (sigui complet o incremental).

Avantatges:

Desavantatges:

Seqüència típica:

  1. Diumenge: Backup complet
  2. Dilluns: Incremental (canvis des de diumenge)
  3. Dimarts: Incremental (canvis des de dilluns)
  4. Dimecres: Incremental (canvis des de dimarts)
    ...
# Backup incremental amb tar
# Es basa en un fitxer "snapshot" que guarda l'estat
tar -czf backup_inc_dia1.tar.gz --listed-incremental=snapshot.snar /home/usuari/documents

Backup Diferencial

Copia els fitxers modificats des de l'últim backup complet.

Avantatges:

Desavantatges:

Seqüència típica:

  1. Diumenge: Backup complet
  2. Dilluns: Diferencial (canvis des de diumenge)
  3. Dimarts: Diferencial (canvis des de diumenge)
  4. Dimecres: Diferencial (canvis des de diumenge)
    ...

Comparació visual

Fitxers:  A  B  C  D  E
          ↓  ↓  ↓  ↓  ↓
Diumenge: C  C  C  C  C  (Complet: A,B,C,D,E)

          A  B* C  D  E*  (* = modificat)
Dilluns:
  - Incremental: B, E
  - Diferencial: B, E

          A  B* C* D  E*
Dimarts:
  - Incremental: C (només el nou canvi)
  - Diferencial: B, C, E (tots des de diumenge)

          A  B* C* D* E*
Dimecres:
  - Incremental: D
  - Diferencial: B, C, D, E

Quan usar cada tipus?

3. Comanda tar

tar (Tape ARchive) és l'eina estàndard per crear arxius a Unix/Linux.

Sintaxi bàsica

tar [opcions] arxiu.tar fitxers...

Opcions principals

Operacions

Compressió

Altres opcions útils

Exemples bàsics

# Crear arxiu sense compressió
tar -cf arxiu.tar directori/

# Crear amb compressió gzip
tar -czf arxiu.tar.gz directori/

# Crear amb compressió bzip2
tar -cjf arxiu.tar.bz2 directori/

# Crear amb compressió xz
tar -cJf arxiu.tar.xz directori/

# Llistar contingut sense extreure
tar -tzf arxiu.tar.gz

# Extreure arxiu
tar -xzf arxiu.tar.gz

# Extreure a un directori específic
tar -xzf arxiu.tar.gz -C /ruta/destí/

# Extreure només alguns fitxers
tar -xzf arxiu.tar.gz fitxer1.txt directori/fitxer2.txt

# Afegir fitxers a un arxiu existent (sense compressió)
tar -rf arxiu.tar nous_fitxers/

Excloure fitxers

# Excloure patrons
tar -czf backup.tar.gz --exclude='*.log' --exclude='tmp/*' directori/

# Excloure múltiples patrons
tar -czf backup.tar.gz \
    --exclude='node_modules' \
    --exclude='*.pyc' \
    --exclude='.git' \
    --exclude='__pycache__' \
    directori/

# Llegir exclusions d'un fitxer
echo "*.log" > exclusions.txt
echo "tmp/" >> exclusions.txt
tar -czf backup.tar.gz --exclude-from=exclusions.txt directori/

4. Backups incrementals amb tar

tar pot fer backups incrementals usant fitxers "snapshot".

Primer backup (complet)

# Crear snapshot inicial i backup complet
tar -czf backup_complet.tar.gz \
    --listed-incremental=snapshot.snar \
    /home/usuari/documents

El fitxer snapshot.snar guarda:

Backups incrementals posteriors

# Primer incremental (canvis des del complet)
tar -czf backup_inc_01.tar.gz \
    --listed-incremental=snapshot.snar \
    /home/usuari/documents

# Segon incremental (canvis des del primer incremental)
tar -czf backup_inc_02.tar.gz \
    --listed-incremental=snapshot.snar \
    /home/usuari/documents

Important: Cada execució actualitza el fitxer snapshot.snar!

Restauració d'incrementals

Per restaurar, cal aplicar els arxius en ordre:

# 1. Restaurar backup complet
tar -xzf backup_complet.tar.gz --listed-incremental=/dev/null

# 2. Aplicar incrementals en ordre
tar -xzf backup_inc_01.tar.gz --listed-incremental=/dev/null
tar -xzf backup_inc_02.tar.gz --listed-incremental=/dev/null

# L'opció --listed-incremental=/dev/null evita errors amb el snapshot

Backups diferencials amb tar

Per fer diferencials, cal mantenir una còpia del snapshot després del backup complet:

# 1. Backup complet
tar -czf backup_complet.tar.gz \
    --listed-incremental=snapshot.snar \
    /home/usuari/documents

# 2. Guardar snapshot per a diferencials
cp snapshot.snar snapshot_base.snar

# 3. Primer diferencial
cp snapshot_base.snar snapshot.snar
tar -czf backup_dif_01.tar.gz \
    --listed-incremental=snapshot.snar \
    /home/usuari/documents

# 4. Segon diferencial (tornar a partir del snapshot base)
cp snapshot_base.snar snapshot.snar
tar -czf backup_dif_02.tar.gz \
    --listed-incremental=snapshot.snar \
    /home/usuari/documents

5. Timestamps i noms de fitxers

És important usar timestamps als noms dels backups:

# Format ISO 8601: YYYY-MM-DD
DATA=$(date +%Y-%m-%d)
tar -czf backup_$DATA.tar.gz directori/

# Amb hora: YYYY-MM-DD_HH-MM-SS
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
tar -czf backup_$TIMESTAMP.tar.gz directori/

# Amb dia de la setmana (per rotació setmanal)
DIA=$(date +%A)  # Dilluns, Dimarts, etc.
tar -czf backup_$DIA.tar.gz directori/

# Amb tipus de backup
TIMESTAMP=$(date +%Y%m%d)
tar -czf backup_complet_$TIMESTAMP.tar.gz ...
tar -czf backup_incremental_$TIMESTAMP.tar.gz ...

6. Verificació d'integritat

Verificar que un arxiu no està corrupte

# Test d'integritat
tar -tzf arxiu.tar.gz > /dev/null
if [ $? -eq 0 ]; then
    echo "Arxiu OK"
else
    echo "Arxiu corrupte!"
fi

# Verificar i mostrar errors
tar -tzf arxiu.tar.gz 2>&1 | grep -i error

Checksums per verificar integritat

# Crear checksum MD5
md5sum backup.tar.gz > backup.tar.gz.md5

# Verificar checksum
md5sum -c backup.tar.gz.md5

# Millor: usar SHA256 (més segur)
sha256sum backup.tar.gz > backup.tar.gz.sha256
sha256sum -c backup.tar.gz.sha256

Comparar arxiu amb directori original

# Llistar fitxers a l'arxiu
tar -tzf backup.tar.gz | sort > arxiu_llista.txt

# Llistar fitxers al directori
find /home/usuari/documents -type f | sort > directori_llista.txt

# Comparar
diff arxiu_llista.txt directori_llista.txt

7. Rotació de backups

Estratègia GFS (Grandfather-Father-Son)

#!/bin/bash

DIA_SETMANA=$(date +%u)  # 1=Dilluns, 7=Diumenge
DIA_MES=$(date +%d)

if [ "$DIA_MES" -eq 1 ]; then
    # Primer dia del mes: backup mensual
    TIPUS="mensual"
    DIRECTORI="backups/mensuals"
elif [ "$DIA_SETMANA" -eq 7 ]; then
    # Diumenge: backup setmanal
    TIPUS="setmanal"
    DIRECTORI="backups/setmanals"
else
    # Altres dies: backup diari
    TIPUS="diari"
    DIRECTORI="backups/diaris"
fi

TIMESTAMP=$(date +%Y-%m-%d)
tar -czf "$DIRECTORI/backup_${TIPUS}_${TIMESTAMP}.tar.gz" /dades/

Neteja automàtica

# Eliminar backups diaris més antics de 7 dies
find backups/diaris/ -name "backup_diari_*.tar.gz" -mtime +7 -delete

# Eliminar backups setmanals més antics de 4 setmanes (28 dies)
find backups/setmanals/ -name "backup_setmanal_*.tar.gz" -mtime +28 -delete

# Eliminar backups mensuals més antics d'1 any (365 dies)
find backups/mensuals/ -name "backup_mensual_*.tar.gz" -mtime +365 -delete

8. Millors pràctiques

  1. Automatitzar: Usar cron per executar backups regularment
  2. Verificar: Sempre comprovar la integritat després de crear el backup
  3. Provar restauracions: Fer proves periòdiques de restauració
  4. Múltiples ubicacions: No guardar backups només al mateix servidor
  5. Xifrar: Considerar xifrar backups amb dades sensibles
  6. Documentar: Mantenir un registre de què, quan i on es fa backup
  7. Monitoritzar: Alertar si un backup falla
  8. Estimar temps: Calcular quan trigarà i quan necessitarà espai

Exemple d'script complet de backup

#!/bin/bash

##############################################
# Script de backup amb logs i verificació
##############################################

# Configuració
ORIGEN="/home/usuari/documents"
DESTI="/backups"
LOG_FILE="/var/log/backup.log"
MAIL_TO="admin@exemple.cat"

# Funció de log
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Funció per enviar email en cas d'error
enviar_alerta() {
    local missatge=$1
    echo "$missatge" | mail -s "ERROR en backup" "$MAIL_TO"
}

# Inici
log "=== Iniciant backup ==="

# Comprovar que existeix l'origen
if [ ! -d "$ORIGEN" ]; then
    log "ERROR: El directori origen no existeix: $ORIGEN"
    enviar_alerta "Directori origen no trobat"
    exit 1
fi

# Crear directori destinació si no existeix
mkdir -p "$DESTI"

# Generar nom del fitxer
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
ARXIU="$DESTI/backup_$TIMESTAMP.tar.gz"
CHECKSUM="$ARXIU.sha256"

# Crear backup
log "Creant arxiu: $ARXIU"
tar -czf "$ARXIU" "$ORIGEN" 2>&1 | tee -a "$LOG_FILE"

if [ ${PIPESTATUS[0]} -eq 0 ]; then
    log "Backup creat correctament"
else
    log "ERROR creant el backup"
    enviar_alerta "Error durant la creació del backup"
    exit 2
fi

# Calcular checksum
log "Calculant checksum..."
sha256sum "$ARXIU" > "$CHECKSUM"

# Verificar integritat
log "Verificant integritat..."
if tar -tzf "$ARXIU" > /dev/null 2>&1; then
    log "Verificació OK"
else
    log "ERROR: Arxiu corrupte!"
    enviar_alerta "Backup corrupte detectat"
    exit 3
fi

# Mostrar estadístiques
MIDA=$(du -h "$ARXIU" | cut -f1)
log "Mida del backup: $MIDA"

# Neteja de backups antics (més de 7 dies)
log "Netejant backups antics..."
find "$DESTI" -name "backup_*.tar.gz" -mtime +7 -delete

log "=== Backup completat amb èxit ==="
exit 0

Resum