MongoDB Yedekleme ve Geri Yükleme: mongodump ve mongorestore Kullanımı

Production veritabanınız çöktüğünde, diskler bozulduğunda ya da yanlışlıkla kritik bir collection silindi. Bu anlar için hazır mısınız? MongoDB yönetiminde en kritik konulardan biri olan yedekleme ve geri yükleme süreçlerini, mongodump ve mongorestore araçlarıyla nasıl sağlam bir şekilde yönetebileceğinizi bu yazıda derinlemesine inceliyoruz.

mongodump ve mongorestore Nedir?

MongoDB, verilerinizi dışa aktarmak için mongodump, içe aktarmak için ise mongorestore araçlarını sunar. Bu iki araç, MongoDB Database Tools paketinin bir parçasıdır ve MongoDB 4.4 sürümünden itibaren sunucudan ayrı olarak dağıtılmaktadır. Yani MongoDB sunucunuzu yükseltseniz bile bu araçları ayrıca güncellemeniz gerekebilir.

mongodump, veritabanınızdaki koleksiyonları BSON formatında dışa aktarır. Bu format, JSON’un ikili (binary) versiyonudur ve daha hızlı okunup yazılabilir. mongorestore ise bu BSON dosyalarını alıp MongoDB’ye geri yükler.

Önce araçların sisteminizde kurulu olup olmadığını kontrol edelim:

mongodump --version
mongorestore --version

Eğer kurulu değilse Ubuntu/Debian üzerinde şöyle kurabilirsiniz:

wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-ubuntu2004-x86_64-100.9.4.deb
sudo dpkg -i mongodb-database-tools-ubuntu2004-x86_64-100.9.4.deb

Temel mongodump Kullanımı

Tüm Veritabanını Yedekleme

En basit kullanım şekliyle tüm MongoDB instance’ınızı yedeklemek:

mongodump --host localhost --port 27017 --out /backup/mongodb/$(date +%Y%m%d_%H%M%S)

Bu komut çalıştığında, belirttiğiniz dizin altında her veritabanı için ayrı bir klasör oluşturur. Her koleksiyon için iki dosya üretir: .bson uzantılı veri dosyası ve .metadata.json uzantılı şema bilgisi dosyası.

Belirli Bir Veritabanını Yedekleme

Üretim ortamında genellikle tek bir veritabanını yedeklemeniz gerekir:

mongodump 
  --host localhost 
  --port 27017 
  --db siparisler 
  --out /backup/mongodb/siparisler_$(date +%Y%m%d)

Kimlik Doğrulamalı Bağlantı

Gerçek dünyada kimlik doğrulamasız MongoDB bırakmak kabul edilemez. Authenticated bağlantı için:

mongodump 
  --uri "mongodb://yedekkullanici:guclusifre@localhost:27017/siparisler?authSource=admin" 
  --out /backup/mongodb/siparisler_$(date +%Y%m%d)

Ya da parametrelerle:

mongodump 
  --host localhost 
  --port 27017 
  --username yedekkullanici 
  --password guclusifre 
  --authenticationDatabase admin 
  --db siparisler 
  --out /backup/mongodb/siparisler_$(date +%Y%m%d)

–uri: MongoDB bağlantı dizesini tek satırda belirtir, production scriptleri için tercih edilir –host: MongoDB sunucusunun adresi –port: Bağlantı portu, varsayılan 27017 –username: Kimlik doğrulama kullanıcı adı –password: Kullanıcı şifresi –authenticationDatabase: Kullanıcının tanımlı olduğu veritabanı, genellikle admin –db: Yedeklenecek veritabanı adı –collection: Sadece belirli bir koleksiyonu yedekler –out: Yedek dosyalarının yazılacağı dizin –gzip: Çıktıyı sıkıştırır, disk kullanımını önemli ölçüde azaltır –oplog: Replica set’lerde point-in-time backup için oplog’u da dahil eder –numParallelCollections: Paralel işlenecek koleksiyon sayısı, varsayılan 4 –excludeCollection: Belirtilen koleksiyonu yedekleme dışı bırakır –query: Belirli bir sorguyla filtrelenmiş verileri yedekler

Sıkıştırmalı Yedekleme

Disk alanı her zaman kısıtlıdır. --gzip parametresiyle yedeklerinizi sıkıştırabilirsiniz:

mongodump 
  --uri "mongodb://yedekkullanici:guclusifre@localhost:27017/?authSource=admin" 
  --gzip 
  --out /backup/mongodb/full_$(date +%Y%m%d_%H%M%S)

Sıkıştırma oranı verinin tipine göre değişir ama genellikle %60-70 arası alan tasarrufu sağlarsınız. Büyük veritabanlarında bu fark çok kritik olabilir.

Arşivi tek bir tar.gz dosyasına da paketleyebilirsiniz:

BACKUP_DIR="/backup/mongodb"
BACKUP_NAME="full_$(date +%Y%m%d_%H%M%S)"

mongodump 
  --uri "mongodb://yedekkullanici:guclusifre@localhost:27017/?authSource=admin" 
  --gzip 
  --archive="${BACKUP_DIR}/${BACKUP_NAME}.archive.gz"

--archive parametresi, tüm yedek verilerini tek bir dosyaya yazar. Bu özellikle S3 veya başka bir uzak depolama alanına aktarırken işinizi kolaylaştırır.

Belirli Koleksiyonları Yedekleme ve Filtreleme

Bazen tüm veritabanını değil, sadece belirli koleksiyonları yedeklemeniz gerekir. Örneğin log koleksiyonlarını genellikle yedeklemeye dahil etmek istemezsiniz:

# Sadece belirli bir koleksiyonu yedekle
mongodump 
  --uri "mongodb://yedekkullanici:guclusifre@localhost:27017/eticaret?authSource=admin" 
  --collection musteriler 
  --out /backup/mongodb/musteriler_$(date +%Y%m%d)

# Log koleksiyonunu hariç tut
mongodump 
  --uri "mongodb://yedekkullanici:guclusifre@localhost:27017/eticaret?authSource=admin" 
  --excludeCollection sistem_loglari 
  --excludeCollection hata_loglari 
  --gzip 
  --out /backup/mongodb/eticaret_$(date +%Y%m%d)

Belirli bir tarih aralığındaki siparişleri yedeklemek gibi senaryo için --query kullanabilirsiniz:

mongodump 
  --uri "mongodb://yedekkullanici:guclusifre@localhost:27017/eticaret?authSource=admin" 
  --collection siparisler 
  --query '{"tarih": {"$gte": {"$date": "2024-01-01T00:00:00Z"}}}' 
  --out /backup/mongodb/siparisler_2024

Otomatik Yedekleme Script’i

El ile yedekleme almak sysadmin işi değil. İşte production’da kullanabileceğiniz kapsamlı bir yedekleme scripti:

#!/bin/bash

# MongoDB Otomatik Yedekleme Scripti
# /usr/local/bin/mongodb_backup.sh

set -euo pipefail

# Konfigürasyon
MONGO_URI="mongodb://yedekkullanici:${MONGO_BACKUP_PASSWORD}@localhost:27017/?authSource=admin"
BACKUP_BASE_DIR="/backup/mongodb"
LOG_FILE="/var/log/mongodb_backup.log"
RETENTION_DAYS=7
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="${BACKUP_BASE_DIR}/${DATE}"

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

# Hata yönetimi
trap 'log "HATA: Satir $LINENO - Yedekleme basarisiz oldu!"' ERR

log "Yedekleme basliyor..."

# Backup dizinini oluştur
mkdir -p "${BACKUP_DIR}"

# Yedekleme al
mongodump 
  --uri "${MONGO_URI}" 
  --gzip 
  --numParallelCollections 4 
  --out "${BACKUP_DIR}" >> "${LOG_FILE}" 2>&1

# Yedek boyutunu hesapla
BACKUP_SIZE=$(du -sh "${BACKUP_DIR}" | cut -f1)
log "Yedekleme tamamlandi. Boyut: ${BACKUP_SIZE}"

# Eski yedekleri temizle
log "Eski yedekler temizleniyor (${RETENTION_DAYS} gunden eski)..."
find "${BACKUP_BASE_DIR}" -maxdepth 1 -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} ; 2>/dev/null || true

# İsteğe bağlı: S3'e yükle
# aws s3 sync "${BACKUP_DIR}" "s3://sirket-yedekler/mongodb/${DATE}/" --storage-class STANDARD_IA

log "Yedekleme sureci tamamlandi."

Bu scripti cron’a ekleyerek otomatize edin:

# Crontab düzenleme
crontab -e

# Her gece 02:00'de çalıştır
0 2 * * * MONGO_BACKUP_PASSWORD='guclusifre' /usr/local/bin/mongodb_backup.sh

mongorestore ile Geri Yükleme

Temel Geri Yükleme

Yedekten geri yüklemenin en temel hali:

mongorestore 
  --uri "mongodb://admin:sifre@localhost:27017/?authSource=admin" 
  --dir /backup/mongodb/20240115_020000

Sıkıştırılmış Yedekten Geri Yükleme

Gzip ile sıkıştırılmış yedekten geri yüklerken --gzip parametresini eklemeniz gerekir:

mongorestore 
  --uri "mongodb://admin:sifre@localhost:27017/?authSource=admin" 
  --gzip 
  --dir /backup/mongodb/20240115_020000

Archive formatındaki yedekten geri yükleme:

mongorestore 
  --uri "mongodb://admin:sifre@localhost:27017/?authSource=admin" 
  --gzip 
  --archive=/backup/mongodb/full_20240115_020000.archive.gz

Önemli mongorestore Parametreleri

–drop: Geri yüklemeden önce mevcut koleksiyonu siler, temiz bir yükleme sağlar –dir: Yedek dosyalarının bulunduğu dizin –archive: Archive formatındaki yedek dosyasının yolu –gzip: Sıkıştırılmış yedek dosyalarını işler –db: Hedef veritabanı adı, farklı bir veritabanına geri yükleme için –collection: Belirli bir koleksiyonu geri yükler –numParallelCollections: Paralel geri yükleme için koleksiyon sayısı –preserveUUID: Koleksiyonların UUID’lerini korur –noIndexRestore: Index’leri yeniden oluşturmaz, büyük veritabanlarında hız kazandırır –maintainInsertionOrder: Belgelerin insertion sırasını korur

Farklı Bir Veritabanına Geri Yükleme

Test ortamına production yedeğini yüklemek çok yaygın bir senaryo. Bu durumda --nsFrom ve --nsTo parametreleri işe yarar:

# Production'daki "eticaret" veritabanını test ortamındaki "eticaret_test" olarak geri yükle
mongorestore 
  --uri "mongodb://admin:sifre@localhost:27017/?authSource=admin" 
  --gzip 
  --nsFrom "eticaret.*" 
  --nsTo "eticaret_test.*" 
  --dir /backup/mongodb/20240115_020000

Sadece Belirli Koleksiyonları Geri Yükleme

# Sadece musteriler koleksiyonunu geri yükle
mongorestore 
  --uri "mongodb://admin:sifre@localhost:27017/?authSource=admin" 
  --gzip 
  --nsInclude "eticaret.musteriler" 
  --drop 
  --dir /backup/mongodb/20240115_020000

Gerçek Dünya Senaryoları

Senaryo 1: Yanlışlıkla Silinen Koleksiyonu Kurtarma

Geliştirici ekibinden biri yanlışlıkla production’da db.siparisler.drop() komutunu çalıştırdı. İşte bu durumda yapılacaklar:

# 1. Adım: Hangi yedeği kullanacağımızı belirle
ls -la /backup/mongodb/

# 2. Adım: Sadece silinen koleksiyonu geri yükle (diğer verilere dokunma)
mongorestore 
  --uri "mongodb://admin:sifre@localhost:27017/?authSource=admin" 
  --gzip 
  --nsInclude "eticaret.siparisler" 
  --dir /backup/mongodb/20240115_020000

# 3. Adım: Geri yüklemeyi doğrula
mongosh --eval "db.getSiblingDB('eticaret').siparisler.countDocuments()"

Senaryo 2: Replica Set Yedeklemesi

Replica set ortamında yedekleme için secondary node’u kullanmak, primary üzerindeki yükü azaltır:

# Secondary node'dan yedek al
mongodump 
  --host "replicaset/mongo1:27017,mongo2:27017,mongo3:27017" 
  --username yedekkullanici 
  --password guclusifre 
  --authenticationDatabase admin 
  --readPreference secondary 
  --oplog 
  --gzip 
  --out /backup/mongodb/replicaset_$(date +%Y%m%d_%H%M%S)

--oplog parametresi, yedekleme sırasında gerçekleşen değişiklikleri de kaydeder. Bu sayede point-in-time bir yedekleme elde etmiş olursunuz. Geri yüklerken --oplogReplay ile bu değişiklikler de uygulanır:

mongorestore 
  --uri "mongodb://admin:sifre@localhost:27017/?authSource=admin" 
  --oplogReplay 
  --gzip 
  --dir /backup/mongodb/replicaset_20240115_020000

Senaryo 3: Yedek Bütünlük Kontrolü

Yedek aldınız ama gerçekten sağlıklı mı? Bunu test etmeden bilemezsiniz. İşte basit bir doğrulama yaklaşımı:

#!/bin/bash
# Yedek doğrulama scripti

BACKUP_DIR="/backup/mongodb/$(ls -t /backup/mongodb/ | head -1)"
TEST_DB_PORT=27018

# Geçici bir MongoDB instance başlat
mongod --port ${TEST_DB_PORT} --dbpath /tmp/mongo_test_restore --fork --logpath /tmp/mongo_test.log

# Yedeği geçici instance'a yükle
mongorestore 
  --host localhost 
  --port ${TEST_DB_PORT} 
  --gzip 
  --dir "${BACKUP_DIR}"

# Koleksiyon sayılarını kontrol et
mongosh --port ${TEST_DB_PORT} --eval "
  db.adminCommand({listDatabases: 1}).databases.forEach(function(d) {
    var dbObj = db.getSiblingDB(d.name);
    var collections = dbObj.getCollectionNames();
    print(d.name + ': ' + collections.length + ' koleksiyon');
    collections.forEach(function(c) {
      print('  ' + c + ': ' + dbObj.getCollection(c).countDocuments() + ' belge');
    });
  });
"

# Geçici instance'ı kapat
mongod --port ${TEST_DB_PORT} --dbpath /tmp/mongo_test_restore --shutdown
rm -rf /tmp/mongo_test_restore /tmp/mongo_test.log

echo "Dogrulama tamamlandi."

Yedekleme için Özel Kullanıcı Oluşturma

Production ortamında yedekleme için admin yetkisi kullanmak doğru değil. Minimum yetkili bir kullanıcı oluşturun:

mongosh --authenticationDatabase admin -u admin -p

# MongoDB Shell'de:
use admin
db.createUser({
  user: "yedekkullanici",
  pwd: "cokguclusifre123!",
  roles: [
    { role: "backup", db: "admin" },
    { role: "restore", db: "admin" }
  ]
})

backup rolü mongodump için, restore rolü ise mongorestore için gereken minimum yetkileri verir.

Yedekleme Boyutu ve Performans İpuçları

Büyük veritabanlarında yedekleme performansı önemli hale gelir:

  • –numParallelCollections: Varsayılan 4 olan bu değeri sunucu kapasitesine göre artırabilirsiniz. Ama dikkatli olun, çok yüksek değerler I/O darboğazı yaratabilir.
  • –excludeCollection: Büyük ve kritik olmayan koleksiyonları (örneğin geçici cache koleksiyonları) dışarıda bırakın.
  • Secondary’den yedekleme: Replica set ortamında mutlaka secondary’den yedek alın, primary üzerindeki baskıyı azaltır.
  • Yedek zamanlaması: Yoğun olmayan saatlerde yedekleme yapın. Gece 02:00-04:00 arası genellikle idealdir.
  • Sıkıştırma kullanın: --gzip hem disk alanından hem de ağ transferi süresinden tasarruf sağlar.
  • Eski yedekleri temizleyin: Disk dolduğunda yeni yedek alınamaz. Retention policy uygulayın.

Sonuç

mongodump ve mongorestore, MongoDB yedekleme stratejinizin temel taşlarıdır. Basit görünebilir ama doğru parametrelerle, doğru zamanlama ve doğru test süreciyle yönetilmedikleri zaman felaket anında sizi mahçup edebilirler.

En önemli nokta şu: Yedekleme almak yetmez, geri yüklemeyi de test etmek zorundasınız. Her ay en az bir kez yedekten geri yükleme yapın ve belge sayılarını, veri tutarlılığını doğrulayın. Geri yüklemeyi hiç test etmemiş bir yedekleme sistemi, olmayan bir sistemden farksızdır.

Production ortamı için minimum gereksinimleriniz şunlar olmalı: otomatik yedekleme scripti, yedeklerin uzak bir konuma (S3, başka bir datacenter) kopyalanması, retention policy, ve aylık geri yükleme testi. Bu dört bileşeni yerine getirdiğinizde gece rahat uyuyabilirsiniz.

Yorum yapın