Veritabanı Performans Testi: pgbench ve sysbench Kullanım Kılavuzu

Veritabanı yönetiminde “iyi çalışıyor” ile “üretim baskısı altında da iyi çalışıyor” arasındaki fark, çoğu zaman ancak bir kriz anında ortaya çıkar. PostgreSQL kurulumunu bitirip “tamam, çalışıyor” diyerek geçen her sysadmin, ileride o sunucuya saniyede yüzlerce sorgu geldiğinde ne olacağını muhtemelen hiç test etmemiştir. Ben de yıllarca öyle yaptım, ta ki üretim ortamında ciddi bir yavaşlama yaşayana kadar.

Bu yazıda pgbench ve sysbench araçlarını kullanarak veritabanı performans testlerini nasıl yapabileceğinizi, sonuçları nasıl yorumlayacağınızı ve gerçek dünya senaryolarında bu araçları nasıl kullanmanız gerektiğini aktaracağım.

Neden Yük Testi Yapmalıyız?

Bir PostgreSQL veya MySQL sunucusu kurduğunuzda, varsayılan konfigürasyon genellikle “çalışır ama optimize değil” modundadır. shared_buffers, work_mem, max_connections gibi parametreler, sunucunuzun RAM ve CPU kapasitesine göre ayarlanmalıdır. Bunu yapmadan önce bir baseline almanız, değişiklik sonrası ise tekrar test etmeniz gerekir.

Yük testi size şunları verir:

  • Mevcut donanımınızın gerçek kapasitesini anlarsınız
  • Konfigürasyon değişikliklerinin etkisini ölçebilirsiniz
  • Darboğazları (CPU, I/O, bellek) önceden tespit edersiniz
  • SLA taahhütleri için somut veri elinizde olur
  • Uygulama geliştiricilerine “sunucu şu kadar QPS kaldırıyor” diyebilirsiniz

pgbench ile PostgreSQL Testi

pgbench, PostgreSQL’in kendi bünyesinde gelen bir yük test aracıdır. Kurulum gerektirmiyor, PostgreSQL ile birlikte geliyor. TPC-B benzeri bir iş yükü simüle eder; banka hesap transferlerini modelleyen tablolar üzerinde çalışır.

pgbench Kurulumu ve İlk Hazırlık

pgbench, postgresql-contrib paketinin içinde değil, doğrudan PostgreSQL ana paketinde gelir. Kontrol edelim:

# Debian/Ubuntu sistemlerde
which pgbench
pgbench --version

# Eğer yoksa
apt install postgresql-client-14

# RHEL/CentOS sistemlerde
yum install postgresql14

Test veritabanını hazırlamak için önce bir veritabanı oluşturup pgbench şemasını initialize etmeniz gerekiyor:

# Test veritabanı oluştur
createdb -U postgres pgbench_test

# pgbench şemasını oluştur, scale factor 50 = yaklaşık 5 milyon satır
pgbench -U postgres -i -s 50 pgbench_test

# Çıktı şöyle görünür:
# dropping old tables...
# creating tables...
# generating data (client-side)...
# 5000000 of 5000000 tuples (100%) done (elapsed 45.23 s, remaining 0.00 s)
# vacuuming...
# creating primary keys...
# done in 67.45 s (drop tables 0.01 s, create tables 0.01 s, ...)

-s (scale factor) parametresi önemli. Değer ne kadar büyükse, veri seti o kadar büyür. 1 = 100.000 satır, 50 = 5.000.000 satır. Testlerinizin üretim veri boyutuna yakın olması için bu değeri üretimdeki verilerinize göre seçin.

Temel pgbench Testi

# 10 bağlantı, 60 saniye süreyle test
pgbench -U postgres 
  -c 10 
  -j 2 
  -T 60 
  pgbench_test

# Parametre açıklamaları:
# -c 10   : 10 eş zamanlı istemci bağlantısı
# -j 2    : 2 thread kullan
# -T 60   : 60 saniye çalış
# -t yerine -T kullanmak süre bazlı test yapar

Çıktı şuna benzer görünür:

starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 50
query mode: simple
number of clients: 10
number of threads: 2
duration: 60 s
number of transactions actually processed: 84523
latency average = 7.099 ms
latency stddev = 4.823 ms
initial connection time = 45.678 ms
tps = 1408.624187 (without initial connection time)

Bu çıktıyı nasıl okuyacaksınız? TPS (transactions per second) değeri en kritik metriktir. Standart sapma ise tutarlılığı gösterir; eğer ortalama gecikme 7ms ama standart sapma 15ms ise, işlemlerin tutarsız sürdüğü anlamına gelir, bu da genellikle lock contention veya I/O burst’ları işaret eder.

İleri Düzey pgbench Kullanımı

Sadece varsayılan TPC-B testi yetmez. Kendi sorgularınızı test etmek için özel script yazabilirsiniz:

# custom_test.sql dosyası oluştur
cat > /tmp/custom_test.sql << 'EOF'
set account_id random(1, 100000)
SELECT abalance FROM pgbench_accounts WHERE aid = :account_id;
UPDATE pgbench_accounts SET abalance = abalance + 100 WHERE aid = :account_id;
EOF

# Bu scriptle test çalıştır
pgbench -U postgres 
  -c 20 
  -j 4 
  -T 120 
  -f /tmp/custom_test.sql 
  pgbench_test

Salt okunur test senaryosu için --select-only veya -S parametresi işe yarar:

# Sadece SELECT sorguları - read-only replica testleri için idealdir
pgbench -U postgres 
  -c 50 
  -j 8 
  -T 300 
  -S 
  pgbench_test

# Çıktıyı dosyaya kaydet ve ayrıntılı log tut
pgbench -U postgres 
  -c 50 
  -j 8 
  -T 300 
  -S 
  --log 
  --log-prefix=/tmp/pgbench_results 
  pgbench_test

Farklı Bağlantı Sayılarıyla Karşılaştırmalı Test

Gerçek dünyada tek bir test sayısıyla karar vermek yanlış olur. Sistemin farklı yük seviyelerindeki davranışını görmek için bir döngü yazabilirsiniz:

#!/bin/bash
# pgbench_sweep.sh - Farklı eş zamanlı bağlantı sayılarını test eder

DB="pgbench_test"
USER="postgres"
DURATION=60
THREAD_COUNT=4

echo "clients,tps,latency_avg,latency_stddev" > /tmp/pgbench_results.csv

for clients in 1 5 10 20 30 50 75 100; do
    echo "Testing with $clients clients..."
    
    result=$(pgbench -U $USER -c $clients -j $THREAD_COUNT -T $DURATION $DB 2>&1)
    
    tps=$(echo "$result" | grep "^tps" | awk '{print $3}')
    lat_avg=$(echo "$result" | grep "latency average" | awk '{print $4}')
    lat_std=$(echo "$result" | grep "latency stddev" | awk '{print $4}')
    
    echo "$clients,$tps,$lat_avg,$lat_std" >> /tmp/pgbench_results.csv
    echo "  -> TPS: $tps, Avg Latency: ${lat_avg}ms"
    
    sleep 10  # Sistemin soğuması için bekle
done

echo "Sonuçlar /tmp/pgbench_results.csv dosyasına kaydedildi"

Bu script sayesinde bağlantı sayısı arttıkça TPS’in nasıl değiştiğini görürsünüz. Tipik olarak belirli bir noktadan sonra TPS düşmeli, gecikme ise artmalıdır. Bu nokta, optimal eş zamanlı bağlantı sayınızdır.

sysbench ile MySQL/MariaDB Testi

sysbench, başlangıçta MySQL için yazılmış ama zamanla çok yönlü bir performans test aracına dönüşmüş bir araçtır. Hem veritabanı hem de sistem kaynaklarını (CPU, bellek, I/O) test edebilirsiniz.

sysbench Kurulumu

# Ubuntu/Debian
apt-get install sysbench

# RHEL/CentOS - önce epel repo ekle
yum install epel-release
yum install sysbench

# Kaynak koddan derleme (en güncel sürüm için)
git clone https://github.com/akopytov/sysbench
cd sysbench
./autogen.sh
./configure
make -j4
make install

OLTP Testi için Hazırlık

sysbench ile MySQL testi yapabilmek için önce test şemasını oluşturmanız gerekiyor:

# MySQL'de test veritabanı oluştur
mysql -u root -p -e "CREATE DATABASE sbtest; CREATE USER 'sbtest'@'localhost' IDENTIFIED BY 'sbtestpass'; GRANT ALL ON sbtest.* TO 'sbtest'@'localhost';"

# sysbench tablolarını hazırla
sysbench oltp_read_write 
  --mysql-host=localhost 
  --mysql-port=3306 
  --mysql-user=sbtest 
  --mysql-password=sbtestpass 
  --mysql-db=sbtest 
  --tables=10 
  --table-size=1000000 
  prepare

# Parametre açıklamaları:
# --tables=10       : 10 ayrı tablo oluştur
# --table-size=1M   : Her tabloda 1 milyon satır
# prepare           : Tabloları hazırla (bir kez çalıştırılır)

OLTP Read-Write Testi

# Karma okuma-yazma testi
sysbench oltp_read_write 
  --mysql-host=localhost 
  --mysql-port=3306 
  --mysql-user=sbtest 
  --mysql-password=sbtestpass 
  --mysql-db=sbtest 
  --tables=10 
  --table-size=1000000 
  --threads=16 
  --time=120 
  --report-interval=10 
  run

--report-interval=10 parametresi her 10 saniyede bir anlık sonuç yazdırır. Bu özellikle uzun süren testlerde sistemin zamanla nasıl davrandığını izlemek için çok değerlidir. Başta yüksek TPS ile başlayıp zamanla düşüyorsa, buffer’ların dolduğunu veya I/O beklemesi yaşandığını gösterir.

Farklı Test Senaryoları

sysbench’in güzel tarafı, farklı iş yüklerini simüle edebilmesidir:

# Salt okunur test - read replica'lar için
sysbench oltp_read_only 
  --mysql-host=localhost 
  --mysql-user=sbtest 
  --mysql-password=sbtestpass 
  --mysql-db=sbtest 
  --tables=10 
  --table-size=1000000 
  --threads=32 
  --time=120 
  run

# Salt yazma testi - write-heavy uygulamalar için
sysbench oltp_write_only 
  --mysql-host=localhost 
  --mysql-user=sbtest 
  --mysql-password=sbtestpass 
  --mysql-db=sbtest 
  --tables=10 
  --table-size=1000000 
  --threads=16 
  --time=120 
  run

# Point select testi - index etkinliğini ölçer
sysbench oltp_point_select 
  --mysql-host=localhost 
  --mysql-user=sbtest 
  --mysql-password=sbtestpass 
  --mysql-db=sbtest 
  --tables=10 
  --table-size=1000000 
  --threads=64 
  --time=60 
  run

sysbench Çıktısını Anlama

Bir test çalışması tamamlandığında şuna benzer bir çıktı görürsünüz:

SQL statistics:
    queries performed:
        read:                            2345678
        write:                           670194
        other:                           335097
        total:                           3350969
    transactions:                        167548 (1395.95 per sec.)
    queries:                             3350969 (27919.02 per sec.)
    ignored errors:                      0      (0.00 per sec.)
    reconnects:                          0      (0.00 per sec.)

Throughput:
    events/s (eps):                      1395.9521
    time elapsed:                        120.0239s
    total number of events:              167548

Latency (ms):
         min:                                    4.53
         avg:                                   11.46
         max:                                  387.23
         95th percentile:                       18.61
         sum:                             1919682.34

Burada dikkat etmeniz gereken kritik metrikler:

  • 95th percentile latency: Sorguların yüzde 95’inin bu süre içinde tamamlandığı değer. 18.61ms demek, 100 sorgudan 95’i 18.61ms altında bitiyor. Maksimum değer 387ms ise bu bir sorun işareti.
  • transactions per sec: Gerçek OLTP kapasiteni gösterir
  • max latency: Büyük farklılıklar lock contention veya I/O gecikmesi işareti olabilir

Gerçek Dünya Senaryosu: Konfigürasyon Optimizasyonu

İşte bu araçların gerçek değeri burada ortaya çıkıyor. Teorik olarak “shared_buffers’ı artırmak performansı iyileştirir” biliyoruz ama ne kadar iyileştirir?

Önce baseline alın, ardından değişiklik yapıp tekrar test edin:

#!/bin/bash
# Konfigürasyon öncesi ve sonrası karşılaştırma scripti

PGHOST="localhost"
PGUSER="postgres"
PGDB="pgbench_test"
CLIENTS=20
THREADS=4
DURATION=120

echo "=== BASELINE TEST ==="
pgbench -h $PGHOST -U $PGUSER 
  -c $CLIENTS -j $THREADS -T $DURATION 
  $PGDB 2>&1 | tee /tmp/baseline_results.txt

echo ""
echo "Şimdi PostgreSQL konfigürasyonunu değiştirin ve yeniden başlatın"
echo "Devam etmek için Enter'a basın..."
read

echo "=== OPTİMİZASYON SONRASI TEST ==="
pgbench -h $PGHOST -U $PGUSER 
  -c $CLIENTS -j $THREADS -T $DURATION 
  $PGDB 2>&1 | tee /tmp/optimized_results.txt

echo ""
echo "=== KARŞILAŞTIRMA ==="
echo "Baseline TPS:"
grep "^tps" /tmp/baseline_results.txt

echo "Optimized TPS:"
grep "^tps" /tmp/optimized_results.txt

Bu scripti çalıştırırken aynı zamanda başka bir terminalde sistemin kaynaklarını izleyin:

# iostat ile disk I/O izle
iostat -x 2

# vmstat ile genel sistem durumu
vmstat 2

# PostgreSQL için pg_stat_activity
psql -U postgres -c "SELECT pid, wait_event_type, wait_event, query FROM pg_stat_activity WHERE state != 'idle';"

Test Sonuçlarını Yorumlarken Dikkat Edilecekler

Performans testi yaparken sık yapılan hataları ve doğru yaklaşımları şöyle özetleyebilirim:

  • Warm-up süresini göz önünde bulundurun: İlk birkaç saniyedeki sonuçlar buffer’lar henüz dolmadığı için yanıltıcı olabilir. Testleri en az 60-120 saniye çalıştırın.
  • Test verisini üretim boyutuna yakın tutun: 1000 satırlık tabloyla yapılan test, tüm veri RAM’e sığdığından gerçekçi değildir.
  • Ağ gecikmesini hesaba katın: pgbench’i veritabanıyla aynı sunucuda mı yoksa uzak bir makinede mi çalıştırdığınız sonuçları önemli ölçüde etkiler.
  • Tekrar edin ve ortalamasını alın: Tek bir test sonucuna güvenmeyin. Aynı testi birkaç kez çalıştırıp tutarlılığını kontrol edin.
  • Sistemin soğuması için bekleyin: Testler arasında en az 30-60 saniye bekleyin ki önceki testin etkileri temizlensin.
  • Eş zamanlı sistem izleme yapın: Testler sırasında htop, iotop, pg_stat_bgwriter gibi araçlarla nelerin tıkandığını görün.

Sonuç

pgbench ve sysbench, veritabanı altyapınızın gerçek kapasitesini anlamanın en doğrudan yoludur. Her konfigürasyon değişikliğinden önce ve sonra bu araçları çalıştırmak, kör uçuşu bırakıp veri ile karar vermeye başlamanızı sağlar.

Özellikle şu durumlarda bu testleri zorunlu görmek gerekir: yeni donanıma geçerken, PostgreSQL veya MySQL sürüm yükseltmeden önce, büyük konfigürasyon değişikliklerinde, ve önemli trafik artışı beklentisi varsa. Üretimde patlama yaşamak yerine test ortamında ölçmek, hem sizi hem de son kullanıcılarınızı korur.

Ölçmediğiniz şeyi yönetemezsiniz, ve veritabanı performansında bu söz hiç bu kadar doğru olmamıştır.

Bir yanıt yazın

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