WordPress Revizyonlarını Sınırlama: Veritabanı Optimizasyonu

Uzun yıllar boyunca WordPress sitelerini yönetirken en sık karşılaştığım sorunların başında şişmiş veritabanları geliyor. Bir gün bir müşterinin sitesine baktım, veritabanı boyutu 2 GB’ı geçmişti ve sitenin tüm içeriği aslında 50-60 MB’ı bulmuyordu. Suçlu? WordPress’in revizyonlama sistemi. Eğer siz de bu durumla karşılaştıysanız ya da karşılaşmadan önce önlem almak istiyorsanız, bu yazı tam size göre.

WordPress Revizyonları Nedir ve Neden Sorun Olur?

WordPress, bir gönderi veya sayfa üzerinde çalışırken her kaydettiğinizde otomatik olarak bir revizyon kaydeder. Bu özellik teoride harika; yanlışlıkla bir şeyleri silerseniz geri dönebilirsiniz. Ama pratikte kontrol altına alınmazsa ciddi problemlere yol açar.

Düşünün: Bir blog yazısı üzerinde 3 saat çalıştınız, her 2 dakikada bir otomatik kayıt devreye girdi. 90 revizyonunuz oldu. Bu bir yazı için 90 satır wp_posts tablosunda, her birinin meta verileri wp_postmeta tablosunda. 500 yazınız varsa ve her birinde ortalama 30 revizyon birikmiş ise, binlerce gereksiz kayıt veritabanınızı dolduruyor demektir.

Bu durum şu sorunlara yol açar:

  • Yavaş sorgular: WordPress sorgu yapısı gereği revizyon kayıtları da wp_posts tablosunu şişirir
  • Yavaş admin paneli: Özellikle Tüm Yazılar ekranı yüklenirken gecikme yaşarsınız
  • Büyük veritabanı yedekleri: Yedek almak ve restore etmek daha uzun sürer
  • Hosting kotası tüketimi: Paylaşımlı hosting kullanıyorsanız veritabanı boyut sınırına takılabilirsiniz
  • Cache verimsizliği: Büyük veritabanı sorguları cache sistemlerini daha çok zorlar

functions.php ile Revizyonları Sınırlamak

En temiz ve taşınabilir çözüm, wp-config.php veya functions.php dosyası üzerinden müdahale etmektir. Ben genellikle functions.php yolunu tercih ediyorum çünkü tema veya eklenti bazında daha granüler kontrol sağlıyor.

Temel Revizyon Limiti Ayarlamak

En basit haliyle, tüm post tipleri için revizyon sayısını sınırlamak istiyorsanız:

// functions.php dosyasina ekleyin
function sysadmin_limit_revisions( $num, $post ) {
    return 5;
}
add_filter( 'wp_revisions_to_keep', 'sysadmin_limit_revisions', 10, 2 );

Bu kod, hangi post tipi veya hangi gönderi olursa olsun maksimum 5 revizyon tutulmasını sağlar. 6. revizyon kaydedildiğinde en eski otomatik olarak silinir.

Post Tipine Göre Farklı Limitler

Gerçek dünyada her içerik tipi aynı revizyon ihtiyacına sahip değildir. Örneğin bir e-ticaret sitesinde ürün açıklamaları sık değişiyor ve belki 3 revizyon yeterlidir, ama hukuki sayfalar için 10 tutmak mantıklı olabilir:

function sysadmin_revisions_by_post_type( $num, $post ) {
    $limits = array(
        'post'    => 5,
        'page'    => 10,
        'product' => 3,
        'portfolio' => 2,
    );

    if ( array_key_exists( $post->post_type, $limits ) ) {
        return $limits[ $post->post_type ];
    }

    // Tanimsiz post tipleri icin varsayilan
    return 3;
}
add_filter( 'wp_revisions_to_keep', 'sysadmin_revisions_by_post_type', 10, 2 );

Bu yaklaşım özellikle WooCommerce sitelerinde fark yaratıyor. Yüzlerce ürününüz varsa ve her ürün için 3 yerine 20 revizyon tutuyorsanız, hesabı siz yapın.

Revizyonları Tamamen Kapatmak

Bazı durumlarda revizyonları sıfır yapmak mantıklıdır. Örneğin sadece programatik olarak içerik güncellenen bir site yönetiyorsanız:

function sysadmin_disable_revisions( $num, $post ) {
    return 0;
}
add_filter( 'wp_revisions_to_keep', 'sysadmin_disable_revisions', 10, 2 );

Dikkat: Revizyonları tamamen kapatmak risklidir. Editörleriniz veya içerik yazarlarınız varsa, yanlışlıkla silinen içerikleri geri getiremezsiniz. Bu seçeneği sadece geliştiricinin dışarıdan içerik beslediği projelerde veya çok kontrollü ortamlarda kullanın.

wp-config.php ile Global Sınır

functions.php dışında, doğrudan wp-config.php dosyasına da sabit bir değer ekleyebilirsiniz. Bu yaklaşım tema değişimlerinden etkilenmez:

// wp-config.php icinde, "That's all, stop editing!" satirinin UZERINDE ekleyin
define( 'WP_POST_REVISIONS', 5 );

Sıfır yaparsanız revizyonlar tamamen devre dışı kalır, true yaparsanız sınırsız olur (zaten varsayılan budur). Ben genellikle bu iki yaklaşımı birlikte kullanıyorum: wp-config.php ile genel bir tavan belirleyip functions.php ile post tipine özel ince ayar yapıyorum.

Mevcut Revizyonları Temizlemek

Limiti ayarlamak yeni revizyonlar için geçerli, ama veritabanında biriken eski revizyonları temizlemez. Bunun için birkaç yöntem var.

WP-CLI ile Temizlik (Önerilen Yöntem)

Eğer sunucuya SSH erişiminiz varsa WP-CLI kullanmak en hızlı ve güvenli yoldur:

# Mevcut revizyon sayisini gormek icin
wp post list --post_type='revision' --format=count

# Tum revizyonlari silmek
wp post delete $(wp post list --post_type='revision' --format=ids) --force

# Bircok revizyon varsa bu komut timeout verebilir, parcali yapmak daha guvenli
wp post list --post_type='revision' --format=ids | xargs -n 100 wp post delete --force

Bu komutları çalıştırmadan önce mutlaka veritabanı yedeği alın:

# Once yedek al
wp db export backup-before-cleanup-$(date +%Y%m%d).sql

# Sonra temizligi yap
wp post delete $(wp post list --post_type='revision' --format=ids) --force

PHP ile Programatik Temizlik

Sunucu erişiminiz yoksa, bir kez çalıştırıp sonra silecek geçici bir PHP dosyası oluşturabilirsiniz. Bunu wp-content içine atın, bir kez çağırın, sonra hemen silin:

<?php
// Bu dosyayi calistirdiktan HEMEN SONRA silin!
// Calistirmadan once veritabani yedeği alin!

define('WP_USE_THEMES', false);
require('../wp-load.php');

global $wpdb;

// Revizyon sayisini say
$count = $wpdb->get_var(
    "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'revision'"
);
echo "Silinecek revizyon sayisi: " . $count . "<br>";

// Revizyon meta verilerini sil
$wpdb->query(
    "DELETE pm FROM $wpdb->postmeta pm
     INNER JOIN $wpdb->posts p ON pm.post_id = p.ID
     WHERE p.post_type = 'revision'"
);

// Revizyonlari sil
$deleted = $wpdb->query(
    "DELETE FROM $wpdb->posts WHERE post_type = 'revision'"
);

echo "Silinen revizyon sayisi: " . $deleted . "<br>";

// Tabloyu optimize et
$wpdb->query("OPTIMIZE TABLE $wpdb->posts");
$wpdb->query("OPTIMIZE TABLE $wpdb->postmeta");

echo "Veritabani optimize edildi.";

phpMyAdmin veya MySQL CLI ile Temizlik

Eğer hosting panelinizden phpMyAdmin’e erişiminiz varsa, SQL sekmesinde şu sorguları çalıştırabilirsiniz:

-- Once kac revizyon oldugunu gormek icin
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'revision';

-- Revizyon meta verilerini sil
DELETE pm FROM wp_postmeta pm
INNER JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.post_type = 'revision';

-- Revizyonlari sil
DELETE FROM wp_posts WHERE post_type = 'revision';

-- Tabloyu optimize et (bo# birakilmis alanlari geri kazanir)
OPTIMIZE TABLE wp_posts;
OPTIMIZE TABLE wp_postmeta;

Önemli Not: wp_posts prefix varsayılan değerdir. Sitenizin farklı bir prefix kullandığını wp-config.php içinde $table_prefix değişkeninden kontrol edin.

Otomatik Periyodik Temizlik

Tek seferlik temizlik yeterli değildir. Uzun vadede veritabanını temiz tutmak için periyodik temizlik kurgulamak gerekir.

WordPress Cron ile Otomatik Temizlik

// Cron islevi tanimla
function sysadmin_cleanup_old_revisions() {
    global $wpdb;

    // Her post icin son 5 revizyon disindakileri sil
    $posts = $wpdb->get_results(
        "SELECT DISTINCT post_parent FROM $wpdb->posts
         WHERE post_type = 'revision' AND post_parent > 0"
    );

    $deleted_total = 0;

    foreach ( $posts as $post ) {
        $keep_ids = $wpdb->get_col(
            $wpdb->prepare(
                "SELECT ID FROM $wpdb->posts
                 WHERE post_type = 'revision'
                 AND post_parent = %d
                 ORDER BY post_date DESC
                 LIMIT 5",
                $post->post_parent
            )
        );

        if ( ! empty( $keep_ids ) ) {
            $ids_placeholder = implode( ',', array_map( 'intval', $keep_ids ) );

            $deleted = $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM $wpdb->posts
                     WHERE post_type = 'revision'
                     AND post_parent = %d
                     AND ID NOT IN ($ids_placeholder)",
                    $post->post_parent
                )
            );

            $deleted_total += $deleted;
        }
    }

    // Log tutmak istersen
    if ( $deleted_total > 0 ) {
        update_option( 'last_revision_cleanup', array(
            'date'    => current_time( 'mysql' ),
            'deleted' => $deleted_total,
        ));
    }
}

// Haftalik cron plani olustur
function sysadmin_schedule_revision_cleanup() {
    if ( ! wp_next_scheduled( 'sysadmin_weekly_revision_cleanup' ) ) {
        wp_schedule_event( time(), 'weekly', 'sysadmin_weekly_revision_cleanup' );
    }
}
add_action( 'wp', 'sysadmin_schedule_revision_cleanup' );
add_action( 'sysadmin_weekly_revision_cleanup', 'sysadmin_cleanup_old_revisions' );

// Plugin/tema deaktive edildiginde cron'u temizle
function sysadmin_cleanup_cron_on_deactivation() {
    wp_clear_scheduled_hook( 'sysadmin_weekly_revision_cleanup' );
}
register_deactivation_hook( __FILE__, 'sysadmin_cleanup_cron_on_deactivation' );

Gerçek Dünya Senaryosu: WooCommerce Sitesi Optimizasyonu

Geçen yıl bir WooCommerce müşterisinin sitesine baktım. 1.200 ürün, 4 editör, 18 ay boyunca hiç revizyon temizliği yapılmamıştı. Durum şuydu:

  • wp_posts tablosu: 847.000 satır
  • Bunun yaklaşık 790.000’i revizyondu
  • Veritabanı boyutu: 1.8 GB
  • Admin paneli product list yükleme süresi: 8-12 saniye

Yaptıklarım sırayla şöyle:

İlk adım olarak wp-config.php dosyasına limit koydum:

define( 'WP_POST_REVISIONS', 3 );

Sonra WP-CLI ile mevcut revizyonları temizledim. Sunucu timeout sorununu önlemek için parcali çalıştırdım:

# Kac revizyon var?
wp post list --post_type='revision' --format=count
# Cikti: 789234

# 500'er parcalar halinde sil
for i in $(seq 1 10); do
  wp post delete $(wp post list --post_type='revision' --format=ids --posts_per_page=500) --force
  echo "Tur $i tamamlandi"
  sleep 2
done

# Veritabanini optimize et
wp db optimize

Ardından tabloları MySQL tarafında da optimize ettim:

# MySQL CLI uzerinden
mysql -u wpuser -p wordpress_db -e "
OPTIMIZE TABLE wp_posts;
OPTIMIZE TABLE wp_postmeta;
OPTIMIZE TABLE wp_options;
"

Sonuç: Veritabanı 1.8 GB’tan 94 MB’a düştü. Ürün listeleme süresi 8-12 saniyeden 0.8-1.2 saniyeye indi. Müşteri “siteye eklenti mi kurdun?” diye sordu, sadece gereksiz veriyi sildim dedim.

Veritabanı Boyutunu İzlemek

Bu işleri yaptıktan sonra izleme kurmak da önemli. Basit bir fonksiyon ile revision sayısını admin bar’da gösterebilirsiniz:

// Sadece adminler icin revizyon sayisini goster
function sysadmin_show_revision_count_in_adminbar( $wp_admin_bar ) {
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }

    global $wpdb;
    $count = $wpdb->get_var(
        "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'revision'"
    );

    if ( $count > 1000 ) {
        $wp_admin_bar->add_node( array(
            'id'    => 'revision-count',
            'title' => '⚠️ Revizyonlar: ' . number_format( $count ),
            'href'  => admin_url( 'tools.php' ),
            'meta'  => array( 'title' => 'Veritabani temizligi gerekebilir' ),
        ));
    }
}
add_action( 'admin_bar_menu', 'sysadmin_show_revision_count_in_adminbar', 100 );

Bu küçük uyarı, sistemi takip eden bir sysadmin için hayat kurtarıcı olabilir.

Dikkat Edilmesi Gereken Noktalar

Revizyonlarla uğraşırken şu hataları yapmayın:

  • Yedeğsiz temizlik yapmak: Her zaman önce yedek, sonra silme işlemi. Bir kere geri dönülmez bir hata yaparsınız, bir daha yapamazsınız.
  • post_parent olmayan revizyonları silmek: Orphan revision kayıtları bazen page builder’ların geçici kayıtlarıdır. Silinmeden önce ne olduklarını anlayın.
  • Çok agresif limit koymak: Özellikle birden fazla editörün çalıştığı sitelerde 0 veya 1 revizyon risklidir. 3-5 makul bir başlangıç noktasıdır.
  • OPTIMIZE TABLE’ı yoğun saatte çalıştırmak: Büyük tablolarda OPTIMIZE işlemi tabloyu kilitleyebilir. Gece saatlerinde çalıştırın.
  • Cron’un çalışıp çalışmadığını kontrol etmemek: WordPress cron’u aslında ziyaretçi isteğine bağlı çalışır. Düşük trafikli sitelerde tetiklenemeyebilir. Gerçek sunucu cron’u ile destekleyin.

Sonuç

WordPress revizyonları iyi niyetle tasarlanmış ama kontrolsüz bırakıldığında veritabanınızı mahveden bir özellik. Bir müşterinin “sitem yavaşladı” şikayetinin ardında çoğu zaman şişmiş revizyon tablosu yatıyor ve çözümü aslında çok basit.

Önerim şu: Bugün hemen wp-config.php dosyanıza define('WP_POST_REVISIONS', 5); ekleyin, ardından WP-CLI veya phpMyAdmin ile mevcut revizyonları temizleyin. Bu iki adım bile ciddi bir performans farkı yaratacak. Eğer birden fazla editörle çalışan bir siteniz varsa, functions.php içinde post tipine göre farklılık gösteren filtre fonksiyonunu kullanın, hem güvenlik hem de performans dengesini iyi kurarsınız.

Ve evet, yedek almayı unutmayın. Her zaman, istisnasız.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir