e4c8d971fc
- scripts/backup.sh: mongodump + bütünlük denetimi, son 14 yedek - scripts/restore.sh: ayrı veritabanına geri yükleme ve sayım karşılaştırma - scripts/backup-pull.sh + systemd zamanlayıcıları; kurulum docs/DEPLOY.md §6 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
3.1 KiB
Bash
Executable File
69 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Yedeği geri yükler ve koleksiyon sayılarını gösterir.
|
||
#
|
||
# restore.sh <yedek.archive.gz | latest> <hedef_db> [--force]
|
||
#
|
||
# - Yedek hangi DB'den alındıysa (dosya adının başı, ör. "kakeibo-…") ondan <hedef_db>'ye aktarılır.
|
||
# - Deneme için ayrı bir hedef kullanın (ör. kakeibo_restore_test); bitince silin:
|
||
# docker exec <konteyner> mongosh --quiet kakeibo_restore_test --eval 'db.dropDatabase()'
|
||
# - Hedef **canlı veritabanının kendisiyse** (felaket sonrası) `--force` gerekir; hedef önce silinir (--drop).
|
||
# - COMPARE_DB=kakeibo verilirse hedefteki sayılar o veritabanıyla karşılaştırılır (fark → çıkış kodu 1).
|
||
#
|
||
# Konteyner backup.sh ile aynı ayarlarla bulunur (MONGO_SERVICE / MONGO_CONTAINER, BACKUP_DIR).
|
||
set -euo pipefail
|
||
|
||
MONGO_SERVICE=${MONGO_SERVICE:-kakeibo-kakeibomongo-fibzhc}
|
||
BACKUP_DIR=${BACKUP_DIR:-/var/backups/kakeibo}
|
||
die() { echo "[kakeibo-restore] HATA: $*" >&2; exit 1; }
|
||
|
||
[[ $# -ge 2 ]] || die "kullanım: restore.sh <yedek|latest> <hedef_db> [--force]"
|
||
src=$1 target=$2 force=${3:-}
|
||
if [[ $src == latest ]]; then
|
||
src=$(ls -1t "$BACKUP_DIR"/*.archive.gz 2>/dev/null | head -n1) || true
|
||
[[ -n $src ]] || die "$BACKUP_DIR içinde yedek yok"
|
||
fi
|
||
[[ -f $src ]] || die "dosya yok: $src"
|
||
[[ $target =~ ^[A-Za-z0-9_-]+$ ]] || die "hedef veritabanı adı geçersiz: $target"
|
||
|
||
# Dosya adı: <db>-YYYY-MM-DD_HHMM.archive.gz
|
||
base=$(basename "$src")
|
||
from=${base%-????-??-??_????.archive.gz}
|
||
[[ $from != "$base" ]] || die "dosya adından kaynak veritabanı anlaşılamadı: $base"
|
||
|
||
container=${MONGO_CONTAINER:-}
|
||
if [[ -z $container ]]; then
|
||
container=$(docker ps -q -f "label=com.docker.swarm.service.name=$MONGO_SERVICE" | head -n1)
|
||
[[ -n $container ]] || container=$(docker ps -q -f "name=$MONGO_SERVICE" | head -n1)
|
||
fi
|
||
[[ -n $container ]] || die "MongoDB konteyneri bulunamadı"
|
||
|
||
drop=()
|
||
exists=$(docker exec "$container" mongosh --quiet --eval \
|
||
"db.adminCommand({listDatabases:1}).databases.some(d => d.name === '$target')")
|
||
if [[ $exists == true ]]; then
|
||
[[ $force == --force ]] || die "'$target' zaten var. Üzerine yazmak için --force (önce silinir)."
|
||
drop=(--drop)
|
||
fi
|
||
|
||
echo "[kakeibo-restore] $base → $target"
|
||
docker exec -i "$container" mongorestore --archive --gzip --quiet "${drop[@]}" \
|
||
--nsInclude="$from.*" --nsFrom="$from.*" --nsTo="$target.*" < "$src" \
|
||
|| die "geri yükleme başarısız (yedek bozuk olabilir). '$target' yarım kalmış olabilir; kontrol edip silin."
|
||
|
||
counts() {
|
||
docker exec "$container" mongosh --quiet "$1" --eval \
|
||
'db.getCollectionNames().sort().map(c => c + " " + db[c].countDocuments({})).join("\n")'
|
||
}
|
||
echo "[kakeibo-restore] $target koleksiyonları (kayıt sayısı):"
|
||
after=$(counts "$target"); echo "$after" | sed 's/^/ /'
|
||
|
||
if [[ -n ${COMPARE_DB:-} ]]; then
|
||
if diff <(counts "$COMPARE_DB") <(echo "$after") >/dev/null; then
|
||
echo "[kakeibo-restore] ✅ $COMPARE_DB ile aynı"
|
||
else
|
||
echo "[kakeibo-restore] ⚠️ $COMPARE_DB ile fark var (yedekten sonra yeni kayıt girildiyse normaldir):"
|
||
diff <(counts "$COMPARE_DB") <(echo "$after") | sed 's/^/ /'
|
||
exit 1
|
||
fi
|
||
fi
|