WP DB ile Veritabanı Yönetimi: Backup, Restore ve Optimize
WordPress veritabanı yönetimi, çoğu sysadmin’in en az sevdiği ama en kritik işlerden biri. Bir şeyler ters gittiğinde “keşke backup almış olsaydım” demek istemezsin. WP-CLI’nin wp db komutu bu işi hem hızlandırıyor hem de scriptlenebilir hale getiriyor. Cron job’lara bağlayabilir, deploy pipeline’larına ekleyebilir, felaket anlarında dakikalar içinde sistemi ayağa kaldırabilirsin.
wp db Nedir ve Neden Kullanmalısın?
wp db, WP-CLI’nin veritabanı işlemlerini komut satırından yapmanı sağlayan alt komut grubudur. phpMyAdmin açmadan, MySQL root şifresi hatırlamaya çalışmadan, doğrudan WordPress yapılandırmasını kullanarak veritabanına bağlanırsın.
Özellikle şu senaryolarda hayat kurtarır:
- Paylaşımlı hostinglerde phpMyAdmin’in import limiti aşıldığında büyük veritabanlarını geri yüklemek
- Staging to production geçişlerinde URL değiştirme işlemleri
- Otomatik backup sistemleri kurarken cron ile entegrasyon
- Veritabanı şişmesini tespit edip temizlemek
- Birden fazla siteyi tek scriptle yönetmek
WP-CLI, wp-config.php dosyasındaki bilgileri otomatik okuduğu için ayrıca bağlantı parametresi girmene gerek yok. Bu büyük bir avantaj.
Temel Bağlantı ve Durum Kontrolü
İşe başlamadan önce veritabanının sağlıklı olup olmadığını kontrol etmek iyi bir alışkanlık.
# Veritabanına bağlantıyı test et
wp db check
# Veritabanı boyutunu görüntüle
wp db size
# Tablo bazında boyut bilgisi
wp db size --tables
# Tüm tabloları listele
wp db tables
# Belirli prefix ile tabloları filtrele
wp db tables --format=csv
wp db check komutu MySQL’in CHECK TABLE işlemini tüm tablolara uygular. Bozuk tablo varsa burada görürsün. Yavaş bir site aldığında ilk çalıştıracağın komutlardan biri bu olmalı.
wp db size --tables çıktısı gerçekten ilginç olabiliyor. Pek çok sitede wp_options tablosunun onlarca megabyte olduğunu görürsün. Bu genellikle transient birikiminin işaretidir.
Backup: Veritabanı Yedekleme
Temel Export İşlemi
# Basit export
wp db export
# Özel dosya adıyla export
wp db export /var/backups/wordpress/backup-$(date +%Y%m%d-%H%M%S).sql
# Belirli tabloları dışarıda bırakarak export (log tabloları gibi)
wp db export backup.sql --exclude_tables=wp_wc_log,wp_actionscheduler_logs,wp_wc_webhooks
# Sadece belirli tabloları export et
wp db export backup.sql --tables=wp_posts,wp_postmeta,wp_options
# Yapı olmadan sadece veriyi export et
wp db export backup.sql --no-create-info
–exclude_tables parametresi özellikle WooCommerce sitelerinde çok işe yarıyor. Action Scheduler logları ve WooCommerce log tabloları gereksiz yere backup boyutunu şişirebiliyor.
Sıkıştırılmış Backup
Büyük veritabanlarında disk alanı kritik olabilir. Doğrudan gzip ile sıkıştırarak export alabilirsin:
# Gzip ile sıkıştırılmış backup
wp db export - | gzip > /var/backups/wp-backup-$(date +%Y%m%d).sql.gz
# Remote sunucuya pipe ile gönder
wp db export - | gzip | ssh user@backup-server "cat > /backups/site-$(date +%Y%m%d).sql.gz"
# Sıkıştırma seviyesini ayarla (1-9, 9 en yüksek sıkıştırma)
wp db export - | gzip -9 > backup.sql.gz
- (tire) işareti, dosyaya yazmak yerine stdout’a çıktı vermesini söyler. Bu sayede pipe zinciri kurabilirsin. Bu yöntemle büyük bir WooCommerce veritabanını %80’e kadar küçültebilirsin.
Otomatik Backup Script’i
Gerçek dünyada manuel backup almak yetmez. Şu script’i /usr/local/bin/wp-backup.sh olarak kaydet:
#!/bin/bash
# Konfigürasyon
WP_PATH="/var/www/html/wordpress"
BACKUP_DIR="/var/backups/wordpress"
RETAIN_DAYS=7
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="$BACKUP_DIR/db-backup-$DATE.sql.gz"
LOG_FILE="/var/log/wp-backup.log"
# Backup dizini yoksa oluştur
mkdir -p "$BACKUP_DIR"
echo "[$DATE] Backup başlıyor..." >> "$LOG_FILE"
# Backup al
if wp --path="$WP_PATH" db export - | gzip > "$BACKUP_FILE"; then
SIZE=$(du -sh "$BACKUP_FILE" | cut -f1)
echo "[$DATE] Backup başarılı: $BACKUP_FILE ($SIZE)" >> "$LOG_FILE"
else
echo "[$DATE] HATA: Backup alınamadı!" >> "$LOG_FILE"
exit 1
fi
# Eski backupları temizle
find "$BACKUP_DIR" -name "db-backup-*.sql.gz" -mtime +$RETAIN_DAYS -delete
echo "[$DATE] $RETAIN_DAYS günden eski backuplar silindi." >> "$LOG_FILE"
exit 0
Cron’a eklemek için:
# Her gün saat 02:00'de backup al
0 2 * * * /usr/local/bin/wp-backup.sh
# Her 6 saatte bir backup al (yoğun siteler için)
0 */6 * * * /usr/local/bin/wp-backup.sh
Restore: Veritabanı Geri Yükleme
Temel Import İşlemi
# Direkt SQL dosyasından import
wp db import backup.sql
# Gzip'li dosyadan import
gunzip -c backup.sql.gz | wp db import -
# Belirli bir path'deki WordPress'e import
wp --path=/var/www/html/site2 db import /backups/site2-backup.sql
Gerçek Dünya Senaryosu: Site Taşıma
Bir siteyi staging’den production’a taşırken en sık yapılan hatalardan biri URL’leri güncellemeyi unutmak. WP-CLI bu işi de halleder:
# 1. Adım: Staging backup al
wp --path=/var/www/staging db export /tmp/staging-export.sql
# 2. Adım: Production veritabanını sıfırla ve import et
wp --path=/var/www/production db reset --yes
wp --path=/var/www/production db import /tmp/staging-export.sql
# 3. Adım: URL'leri güncelle
wp --path=/var/www/production search-replace 'https://staging.site.com' 'https://www.site.com' --skip-columns=guid
# 4. Adım: Cache temizle
wp --path=/var/www/production cache flush
wp --path=/var/www/production rewrite flush
–skip-columns=guid önemli bir detay. GUID kolonunu değiştirmemek, post revizyonlarının ve medya dosyalarının referanslarının bozulmasını engeller.
Multisite Senaryosu
# Multisite restore sonrası URL güncelleme
wp --path=/var/www/multisite --url=http://main-site.com search-replace
'http://old-domain.com'
'http://new-domain.com'
--network
--skip-columns=guid
--dry-run
# Dry run başarılıysa --dry-run'ı kaldır ve çalıştır
wp --path=/var/www/multisite --url=http://main-site.com search-replace
'http://old-domain.com'
'http://new-domain.com'
--network
--skip-columns=guid
--dry-run parametresini asla atlama. Kaç tane değişiklik yapılacağını önce görmek, geri dönülemez hataların önüne geçer.
Optimize: Veritabanı Performans İyileştirme
Temel Optimizasyon
# Tüm tabloları optimize et
wp db optimize
# Belirli tabloları optimize et
wp db optimize --tables=wp_posts,wp_postmeta
# Tablo onarımı
wp db repair
# Yapı kontrolü ile birlikte
wp db check && wp db repair && wp db optimize
wp db optimize aslında MySQL’in OPTIMIZE TABLE komutunu çalıştırır. Silinen kayıtların bıraktığı boşlukları geri kazanır ve tablo fragmentasyonunu giderir. Çok satır silinen tablolarda belirgin performans artışı sağlar.
Transient Temizleme
WordPress’in en büyük veritabanı şişirme nedenlerinden biri süresi dolmuş transient’lar. Pek çok eklenti temizlemeyi ihmal eder:
# Süresi dolmuş transient'ları sil
wp transient delete --expired
# Tüm transient'ları sil (dikkatli kullan!)
wp transient delete --all
# Kaç transient var kontrol et
wp db query "SELECT COUNT(*) FROM wp_options WHERE option_name LIKE '%_transient_%'"
# Büyük transient'ları bul
wp db query "SELECT option_name, LENGTH(option_value) as size FROM wp_options WHERE option_name LIKE '%_transient_%' ORDER BY size DESC LIMIT 10"
Son komut çok değerli bilgi verir. Hangi eklentinin ne kadar büyük transient bıraktığını görebilirsin. Bazen tek bir eklentinin birkaç megabyte transient bıraktığını görürsün.
wp_options Temizleme
wp_options tablosu zamanla bir çöp kutusu haline gelebilir. Silinen eklentilerin verileri, orphaned metadata, bozuk cache verileri burada birikir:
# wp_options boyutunu kontrol et
wp db query "SELECT COUNT(*), SUM(LENGTH(option_value)) / 1024 / 1024 as total_mb FROM wp_options"
# Autoload edilen seçeneklerin boyutu
wp db query "SELECT COUNT(*), SUM(LENGTH(option_value)) / 1024 as total_kb FROM wp_options WHERE autoload='yes'"
# En büyük autoload seçenekleri listele
wp db query "SELECT option_name, LENGTH(option_value) as size FROM wp_options WHERE autoload='yes' ORDER BY size DESC LIMIT 20"
# Belirli bir eklentinin bıraktığı verileri temizle
wp db query "DELETE FROM wp_options WHERE option_name LIKE 'eski_eklenti_%'"
Dikkat: wp_options üzerinde direkt silme işlemi yapmadan önce mutlaka backup al. Yanlış bir silme işlemi siteyi tamamen bozabilir.
Post Revizyonlarını Temizleme
WooCommerce ve içerik yoğun sitelerde revizyonlar veritabanını ciddi ölçüde şişirebilir:
# Kaç revizyon var?
wp db query "SELECT COUNT(*) FROM wp_posts WHERE post_type='revision'"
# 5'ten fazla revizyonu olan postları bul ve fazlaları sil
wp post delete $(wp post list --post_type='revision' --format=ids) --force
# Ya da doğrudan SQL ile (daha hızlı)
wp db query "DELETE FROM wp_posts WHERE post_type = 'revision'"
wp db query "DELETE pm FROM wp_postmeta pm LEFT JOIN wp_posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL"
Ikinci yöntem çok daha hızlı çalışır ama orphaned postmeta’yı da temizlemek için ikinci komutu çalıştırmayı unutma.
İleri Seviye wp db Kullanımı
Doğrudan Query Çalıştırma
# Tek satır sorgu
wp db query "SELECT * FROM wp_users LIMIT 5"
# Çoklu sorgu dosyası çalıştır
wp db query < /tmp/cleanup-queries.sql
# Sonucu dosyaya yaz
wp db query "SELECT post_title, post_status FROM wp_posts" > /tmp/posts-list.txt
# Interaktif MySQL shell'e gir
wp db cli
wp db cli komutu seni direkt MySQL konsoluna atar. Bağlantı bilgilerini elle girmene gerek kalmadan WordPress’in veritabanına bağlanırsın. Uzun ve karmaşık sorguları test ederken çok kullanışlı.
Veritabanı Prefix Sorunlarını Çözme
Güvenlik nedeniyle prefix değiştirirken veya bir siteyi farklı prefix ile import ettikten sonra:
# Mevcut tabloları listele
wp db tables
# wp_usermeta ve wp_options içindeki prefix referanslarını güncelle
wp db query "UPDATE wp_options SET option_name = REPLACE(option_name, 'wp_', 'yeni_') WHERE option_name LIKE 'wp_%'"
wp db query "UPDATE wp_usermeta SET meta_key = REPLACE(meta_key, 'wp_', 'yeni_') WHERE meta_key LIKE 'wp_%'"
Performans Analizi
# En büyük tabloları listele
wp db query "SELECT table_name, ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.tables WHERE table_schema = DATABASE() ORDER BY size_mb DESC LIMIT 10"
# Fragmente olmuş tabloları bul
wp db query "SELECT table_name, data_free / 1024 / 1024 AS free_mb FROM information_schema.tables WHERE table_schema = DATABASE() AND data_free > 1048576 ORDER BY free_mb DESC"
# Index kullanım durumu
wp db query "SHOW TABLE STATUS"
Pratik Senaryo: WooCommerce Veritabanı Temizliği
WooCommerce siteleri özellikle hızlı kirlenir. Şu script haftalık çalıştırılabilir:
#!/bin/bash
WP_PATH="/var/www/html/woocommerce-site"
echo "WooCommerce DB temizliği başlıyor..."
# 1. Süresi dolmuş transient'ları temizle
wp --path="$WP_PATH" transient delete --expired
echo "Transient'lar temizlendi."
# 2. Tamamlanmış action scheduler loglarını temizle (90 günden eski)
wp --path="$WP_PATH" db query "DELETE FROM wp_actionscheduler_logs WHERE log_date < DATE_SUB(NOW(), INTERVAL 90 DAY)"
wp --path="$WP_PATH" db query "DELETE FROM wp_actionscheduler_actions WHERE status = 'complete' AND scheduled_date_gmt < DATE_SUB(NOW(), INTERVAL 90 DAY)"
echo "Action Scheduler logları temizlendi."
# 3. WooCommerce session'larını temizle (süresi dolmuş)
wp --path="$WP_PATH" db query "DELETE FROM wp_woocommerce_sessions WHERE session_expiry < UNIX_TIMESTAMP()"
echo "WooCommerce session'ları temizlendi."
# 4. Optimize et
wp --path="$WP_PATH" db optimize
echo "Veritabanı optimize edildi."
# 5. Son boyutu raporla
echo "Veritabanı boyutu:"
wp --path="$WP_PATH" db size
Bu script özellikle yüksek trafikli WooCommerce sitelerinde haftalık çalıştırıldığında veritabanı boyutunu önemli ölçüde küçültebilir. Aylarca çalışmış bir sitede bu işlemin sonunda veritabanı boyutunun %40-50 küçüldüğüne sıkça rastlanır.
Hata Ayıklama ve Sorun Giderme
Yaygın Hatalar ve Çözümleri
“Error establishing a database connection” hatası sonrası:
# wp-config.php bilgilerini doğrula
wp config get DB_NAME
wp config get DB_HOST
wp config get DB_USER
# Bağlantı testi
wp db check
# Tablo bütünlüğünü kontrol et
wp db repair
Import sırasında “MySQL server has gone away” hatası:
# Büyük dosyaları parçalara bölerek import et
split -l 50000 backup.sql chunk_
for f in chunk_*; do
wp db import "$f"
echo "$f import edildi"
done
rm chunk_*
Charset sorunları (özellikle Türkçe karakter bozulması):
# Charset bilgisini kontrol et
wp db query "SHOW VARIABLES LIKE 'character_set%'"
# Export sırasında charset belirt
wp db export --default-character-set=utf8mb4 backup.sql
Backup Doğrulama
Backup aldıktan sonra doğrulamak kritik. Geri yükleyemeyeceğin bir backup’ın değeri yok:
# Backup dosyasının bütünlüğünü kontrol et
gunzip -t backup.sql.gz && echo "Dosya sağlam" || echo "DOSYA BOZUK!"
# İçinde tablo var mı kontrol et
gunzip -c backup.sql.gz | grep "CREATE TABLE" | wc -l
# Test ortamında restore et ve kontrol et
wp --path=/var/www/test db reset --yes
gunzip -c backup.sql.gz | wp --path=/var/www/test db import -
wp --path=/var/www/test db check
Özellikle production ortamlarında ayda bir bu doğrulama testini yapmak iyi bir pratik. “Backup var” demek ile “çalışan backup var” demek farklı şeyler.
wp db ile Güvenlik Pratikleri
Backup dosyaları son derece hassas veriler içerir. Kullanıcı şifreleri hash’lenmiş olsa da e-posta adresleri, sipariş bilgileri ve kişisel veriler düz metin olarak bulunur.
# Backup dosyasına sadece gerekli kullanıcı erişsin
chmod 600 /var/backups/wordpress/backup.sql.gz
chown root:root /var/backups/wordpress/backup.sql.gz
# Web erişilebilir dizinlere backup alma
# YANLIS:
wp db export /var/www/html/backup.sql
# DOGRU:
wp db export /var/backups/wordpress/backup.sql
# Şifreli backup (gpg ile)
wp db export - | gzip | gpg --symmetric --cipher-algo AES256 > backup.sql.gz.gpg
Backup dizinini web server’ın erişemeyeceği bir yerde tutmak temel güvenlik pratiği. /var/www altına backup alan siteler maalesef hala çok yaygın.
Sonuç
wp db komutu, WordPress veritabanı yönetimini scriptlenebilir ve tekrarlanabilir bir hale getiriyor. Manuel phpMyAdmin işlemlerinden kurtulup otomatize bir sistemin olduğunda hem zaman kazanırsın hem de insan hatasını minimize edersin.
En önemli alışkanlıklar şunlar:
- Backup’ları otomatize et, manuel alma isteğe bağlı kalmasın
- Restore test et, backup aldım demek yetmez
- Optimize işlemini düzenli yap, haftalık veya aylık
- Büyük işlemler öncesi backup al, search-replace gibi toplu değişikliklerden önce
- Backup dosyalarını güvenli tut, web erişimine kapatılmış dizinlerde sakla
WP-CLI olmadan yapılan işlemlerin büyük çoğunluğu ya hata yapmaya müsait ya da ölçeklenemiyor. Birden fazla WordPress sitesi yönetiyorsan, bu komutları öğrenmek için harcayacağın birkaç saatlik zaman, ileride karşılaşacağın sorunlarda seni defalarca kurtaracak.
