#!/usr/bin/env bash
set -eo pipefail
DB_NAME="my_production_db"
DB_USER="postgres"
BUCKET_NAME="my-backups-bucket"
B2_ENDPOINT="https://s3.eu-central-003.backblaze.com" # Schimbă cu regiunea ta B2
BACKUP_DIR="/tmp/backups"
DATE=$(date +%Y-%m-%d-%H%M%S)
FILENAME="$DB_NAME-$DATE.sql.gz"
mkdir -p "$BACKUP_DIR"
echo "Pornire backup pentru $DB_NAME..."
# Folosim pg_dump direct. Parola trebuie să fie în ~/.pgpass ca să nu o scriem în clar aici
pg_dump -U "$DB_USER" -h localhost "$DB_NAME" | gzip > "$BACKUP_DIR/$FILENAME"
echo "Urcare în Backblaze B2..."
aws s3 cp "$BACKUP_DIR/$FILENAME" "s3://$BUCKET_NAME/$FILENAME" \
--endpoint-url "$B2_ENDPOINT" \
--profile b2
echo "Curățare fișier local..."
rm "$BACKUP_DIR/$FILENAME"
echo "Backup finalizat cu succes!"Am văzut prea des startup-uri care își țin backup-urile pe aceeași mașină virtuală cu baza de date. E o rețetă sigură pentru dezastru. Astăzi vă arăt cum am mutat backup-urile pentru un proiect cu 12.000 de utilizatori activi direct în Backblaze B2, folosind un script simplu de bash, pg_dump și cron. Costă sub 1 dolar pe lună și te scapă de nopți nedormite.
Am trecut prin destule incidente neplăcute în cei peste 10 ani de dev ca să știu că un backup pe care nu l-ai restaurat măcar o dată este egal cu zero. La proiectul de care vă zic, aveam nevoie de o soluție ieftină, rapidă și redundantă. AWS S3 devenea cam scump la stocare pe termen lung, așa că am ales Backblaze B2. Au API compatibil cu S3, iar prețul e de vreo 4 ori mai mic. Am economisit cam 40$ pe lună doar din mutarea asta simplă.
De ce setup-ul ăsta și care e compromisul?
Folosim pg_dump pentru că e sfânt. Face dump logic, e ușor de citit și e independent de versiunea minoră de Postgres. Ca stocare, Backblaze B2 ne oferă primii 10 GB gratis, iar după aia e în jur de 0.006$/GB/lună.
Dar există și un trade-off sincer. La baze de date de peste 80-100 GB, pg_dump devine lent și blochează resurse de I/O pe server în timpul rulării. Dacă ai DB-uri gigantice, va trebui să te uiți spre backup-uri fizice gen pgBackRest. Pentru baze medii însă, scriptul nostru e perfect.
Cum integrăm totul
Mai întâi, ai nevoie de awscli instalat pe server. Da, folosesc tool-ul oficial de AWS pentru că Backblaze are API compatibil S3 și e mult mai stabil decât tool-ul lor nativ b2-tools.
Configurezi profilul de AWS cu credențialele din B2 (Application Key și Key ID):
aws configure --profile b2
Scriptul pe care îl găsiți mai jos face dump-ul bazei, îl comprimă cu gzip ca să economisim spațiu (am redus dimensiunea de la 12GB la 1.8GB în cazul meu) și îl urcă în bucket-ul securizat.
Automatizarea cu Cron
Nu vrei să rulezi asta manual în fiecare zi. Adăugăm un job în crontab să ruleze în fiecare noapte la ora 03:00, când traficul este minim:
0 3 * * * /usr/local/bin/backup_db.sh >> /var/log/db_backup.log 2>&1
Am redirecționat output-ul într-un fișier de log pentru că, din experiență, cândva o să crape (de obicei din cauza lipsei de spațiu temporar pe disc sau modificări de permisiuni) și vrei să știi exact de ce.
Partea pe care o ignoră mulți devops: Testul de Restore
Degeaba ai fișiere în cloud dacă sunt corupte. Am pățit o dată să am backup-uri goale (0 bytes) timp de o lună pentru că scriptul nu avea drepturi de scriere în folderul temporar, dar returna exit code 0 din cauza unui pipe prost configurat.
Cum testezi restore-ul rapid într-un container local de Docker:
-
Descarcă backup-ul:
aws s3 cp s3://bucket-ul-tau/backup-db.sql.gz . --endpoint-url https://s3.eu-central-003.backblaze.com --profile b2 -
Dezarhivează-l:
gunzip backup-db.sql.gz -
Rulează un Postgres curat în Docker și injectează datele:
docker run --name pg-test -e POSTGRES_PASSWORD=test -d postgres:15docker exec -i pg-test psql -U postgres -d postgres < backup-db.sql
Dacă procesul se termină fără erori majore de sintaxă sau tabele lipsă, ești în siguranță.
Voi cum vă asigurați că backup-urile chiar funcționează? Automatizați și testul de restore într-un mediu de staging sau mergeți pe încredere și speranță?