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_poststablosunu ş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_poststablosu: 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_parentolmayan 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.
