Swap Alanı Sorunları: Yetersiz ve Hatalı Swap Yapılandırmasını Giderme

Bir gün üretim sunucunuza bağlandığınızda Out of Memory hataları görüyorsunuz, uygulamalar çöküyor ve sistem neredeyse donma noktasına gelmiş. Swap alanına bakıyorsunuz, ya tamamen dolu ya da hiç yapılandırılmamış. Bu senaryo sysadminlerin kabusu olabilir ama aslında çözümü oldukça sistematik bir süreç. Bu yazıda swap sorunlarını kökten nasıl çözeceğinizi, doğru yapılandırmayı nasıl yapacağınızı ve izleme stratejilerini ele alacağız.

Swap Nedir ve Neden Önemlidir?

Swap, RAM dolduğunda Linux çekirdeğinin kullanılmayan bellek sayfalarını diske taşıdığı bir alan. Disk tabanlı olduğu için RAM’den çok daha yavaş ama hiç swap olmaması, bellek baskısı altındaki sistemlerde OOM Killer’ın devreye girerek süreçleri öldürmesine yol açar. Bu da kritik servislerinizin aniden kapanması demek.

Swap sadece “RAM yetersiz olduğunda kullanılan yer” değil, aynı zamanda sistemin stabilitesini koruyan bir güvenlik ağı. Özellikle bulut ortamlarında küçük instance’larda çalışan servisler için swap hayat kurtarıcı olabilir.

Mevcut Swap Durumunu Teşhis Etme

Sorun gidermeye başlamadan önce mevcut durumu net olarak görmemiz gerekiyor.

# Swap durumunu özet olarak görme
free -h

# Detaylı swap bilgisi
swapon --show

# /proc üzerinden swap bilgisi
cat /proc/swaps

# Swap kullanım yüzdesini anlık izleme
watch -n 2 'free -h && echo "---" && swapon --show'

free -h çıktısında şunu görürsünüz:

              total        used        free      shared  buff/cache   available
Mem:           7.7G        5.2G        800M        234M        1.7G        2.1G
Swap:          2.0G        1.8G        200M

Swap’ın neredeyse dolu olması (%90 üzeri) ciddi bir uyarı işareti. Sistem RAM ile swap arasında sürekli veri taşıyorsa buna thrashing denir ve bu durum sistemi felç eder.

Swap Kullanan Süreçleri Bulma

# Her sürecin swap kullanımını listele (MB cinsinden)
for pid in /proc/[0-9]*; do
    pid_num=$(basename $pid)
    if [ -f "$pid/status" ]; then
        swap=$(grep VmSwap "$pid/status" 2>/dev/null | awk '{print $2}')
        if [ -n "$swap" ] && [ "$swap" -gt 0 ] 2>/dev/null; then
            name=$(cat "$pid/comm" 2>/dev/null)
            echo "$swap kB - PID: $pid_num - $name"
        fi
    fi
done | sort -rn | head -20

Bu script size en fazla swap kullanan 20 süreci sıralı olarak gösterir. Genellikle bir veya iki “suçlu” süreç hemen dikkat çeker.

Swap Alanı Oluşturma

Swap Partition vs Swap File

Geleneksel yaklaşım ayrı bir partition ayırmak, ancak modern sistemlerde swap dosyası kullanmak çok daha esnek. Bulut ortamlarında partition yeniden boyutlandırmak zahmetli, swap dosyasını ise dakikalar içinde değiştirebilirsiniz.

Swap Dosyası Oluşturma:

# 4GB swap dosyası oluştur
sudo fallocate -l 4G /swapfile

# Güvenlik için izinleri kısıtla
sudo chmod 600 /swapfile

# Swap olarak formatla
sudo mkswap /swapfile

# Swap'ı aktif et
sudo swapon /swapfile

# Kalıcı hale getir (fstab'a ekle)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Doğrulama
swapon --show

fallocate bazı dosya sistemlerinde (özellikle btrfs) sorun çıkarabilir. Bu durumda alternatif:

# btrfs veya xfs için dd kullan
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress

Swap Partition ile Çalışma

Eğer ayrı bir disk alanınız varsa ve partition oluşturmak istiyorsanız:

# Mevcut diskleri listele
lsblk

# fdisk ile partition oluştur (örnek: /dev/sdb)
sudo fdisk /dev/sdb
# n -> new partition
# p -> primary
# varsayılan değerler -> Enter
# t -> tip değiştir -> 82 (Linux swap)
# w -> yaz ve çık

# Swap olarak formatla
sudo mkswap /dev/sdb1

# UUID'yi al ve fstab'a ekle
UUID=$(blkid -s UUID -o value /dev/sdb1)
echo "UUID=$UUID none swap sw 0 0" | sudo tee -a /etc/fstab

# Aktif et
sudo swapon -a

Swappiness Ayarı: En Çok Yanlış Anlaşılan Parametre

vm.swappiness değeri çekirdeğin swap kullanma eğilimini belirler. 0 ile 100 arasında bir değer alır.

  • 0: Çekirdek swap kullanmaktan kaçınır, sadece zorunlu durumlarda kullanır
  • 10: Sunucular için yaygın tercih, düşük swap kullanımı
  • 60: Varsayılan değer, masaüstü sistemler için makul
  • 100: Çekirdek agresif biçimde swap kullanır
# Mevcut swappiness değerini görme
cat /proc/sys/vm/swappiness

# Anlık değiştirme (reboot'ta sıfırlanır)
sudo sysctl vm.swappiness=10

# Kalıcı yapma
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Değişikliği doğrula
sysctl vm.swappiness

Veritabanı sunucuları (MySQL, PostgreSQL) için swappiness değerini 1-10 arasında tutmanızı öneririm. PostgreSQL belgelerinde de bu konu özellikle vurgulanır, swap’a düşen bir veritabanı sorgu performansını dramatik biçimde kaybeder.

vfs_cache_pressure Ayarı

Swappiness ile birlikte düşünülmesi gereken bir diğer parametre:

# Varsayılan 100, dosya sistemi önbelleğini ne kadar agresif boşaltacağını belirler
cat /proc/sys/vm/vfs_cache_pressure

# Swap dosyasıyla birlikte önerilen ayar
sudo sysctl vm.vfs_cache_pressure=50
echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf

Yaygın Swap Sorunları ve Çözümleri

Sorun 1: Swap Aktif Edilemiyor

# Hata: "swapon: /swapfile: read swap header failed"
# Çözüm: Dosyayı yeniden formatla
sudo swapoff /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Eğer fallocate ile oluşturulan dosyada sorun yaşıyorsanız:

# Dosyanın içini kontrol et
file /swapfile
# Çıktı "Linux/i386 swap file" içermeli

# Eğer içermiyorsa sıfırdan oluştur
sudo swapoff /swapfile 2>/dev/null
sudo rm /swapfile
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Sorun 2: Swap Dolu ve Sistem Yavaş

Bu senaryoda önce swap’ı boşaltmaya çalışırız. Ancak bunu yapmak için yeterli RAM olması gerekir:

# Önce ne kadar RAM müsait olduğunu kontrol et
free -h

# Eğer yeterli RAM varsa swap'ı temizle
sudo swapoff -a && sudo swapon -a

# Süreç bazlı müdahale - en fazla RAM kullanan süreçleri göster
ps aux --sort=-%mem | head -10

Gerçek dünya senaryosu: Bir web sunucusunda Apache worker’larının bellek sızıntısı yaptığını ve swap’ı tamamen doldurduğunu gördüm. Acil çözüm şöyle oldu:

# Apache'yi yeniden başlat (worker'ları temizler)
sudo systemctl restart apache2

# Bellek sızıntısı kontrolü için periyodik yeniden başlatma
# /etc/cron.d/apache-restart dosyasına ekle:
# 0 3 * * * root /bin/systemctl restart apache2

Sorun 3: fstab’da Yanlış Swap Yapılandırması

Sistem boot’ta swap mount edilmiyorsa:

# fstab içeriğini kontrol et
cat /etc/fstab | grep swap

# UUID ile doğru entry olduğundan emin ol
blkid /swapfile
# veya
blkid /dev/sdXY

# fstab test et
sudo mount -a
# Hata yoksa yapılandırma doğru

# Swap özelinde test
sudo swapon -a
sudo swapon --show

Sorun 4: Encrypted Swap Yapılandırması

Hassas verileri olan sistemlerde swap şifrelenmeli, aksi halde bellek içerikleri diske yazılır:

# crypttab ile şifreli swap
# /etc/crypttab dosyasına ekle:
echo "cryptswap1 /dev/sda3 /dev/urandom swap,offset=8" | sudo tee -a /etc/crypttab

# /etc/fstab'ı güncelle
echo "/dev/mapper/cryptswap1 none swap sw 0 0" | sudo tee -a /etc/fstab

# Yapılandırmayı uygula
sudo systemctl daemon-reload

ZRAM: Disk Yerine RAM’de Sıkıştırılmış Swap

Disk I/O’sunun dar boğaz olduğu sistemlerde ZRAM mükemmel bir alternatif. Swap alanını RAM’de sıkıştırılmış bloklar olarak tutar.

# zram-tools kurulumu (Debian/Ubuntu)
sudo apt install zram-tools

# veya zramswap
sudo apt install zramswap-enabler

# Manuel ZRAM kurulumu
sudo modprobe zram

# 2GB ZRAM oluştur
echo 2G | sudo tee /sys/block/zram0/disksize
sudo mkswap /dev/zram0
sudo swapon /dev/zram0 -p 100  # Yüksek öncelik ver

# ZRAM durumunu kontrol et
zramctl

ZRAM için öncelik değeri önemli: -p 100 ile ZRAM’ı normal swap’tan önce kullanmasını sağlıyoruz. Bellek sıkıştırma oranı genellikle 2:1 ile 4:1 arasında.

Swap İzleme ve Alerting

Sorunları proaktif yakalamak için izleme şart.

#!/bin/bash
# swap_monitor.sh - Swap kullanımını izle ve uyar
THRESHOLD=80
SWAP_TOTAL=$(free | grep Swap | awk '{print $2}')
SWAP_USED=$(free | grep Swap | awk '{print $3}')

if [ "$SWAP_TOTAL" -gt 0 ]; then
    SWAP_PERCENT=$(( SWAP_USED * 100 / SWAP_TOTAL ))
    
    if [ "$SWAP_PERCENT" -gt "$THRESHOLD" ]; then
        echo "UYARI: Swap kullanimi %$SWAP_PERCENT (Esik: %$THRESHOLD)"
        echo "En fazla swap kullanan süreçler:"
        for pid in /proc/[0-9]*; do
            pid_num=$(basename $pid)
            swap=$(grep VmSwap "$pid/status" 2>/dev/null | awk '{print $2}')
            if [ -n "$swap" ] && [ "$swap" -gt 1024 ] 2>/dev/null; then
                name=$(cat "$pid/comm" 2>/dev/null)
                echo "  $((swap/1024)) MB - $name (PID: $pid_num)"
            fi
        done | sort -rn
        # Mail göndermek için:
        # | mail -s "Swap Uyarisi: $(hostname)" [email protected]
    else
        echo "Swap normal: %$SWAP_PERCENT"
    fi
else
    echo "KRITIK: Swap alani bulunamadi!"
fi

Bu scripti cron’a ekleyin:

# Her 5 dakikada bir çalıştır
echo "*/5 * * * * root /usr/local/bin/swap_monitor.sh >> /var/log/swap_monitor.log 2>&1" | sudo tee /etc/cron.d/swap-monitor

# Script'i çalıştırılabilir yap
sudo chmod +x /usr/local/bin/swap_monitor.sh

OOM Killer ile Swap İlişkisi

Swap yoksa veya doluysa OOM Killer devreye girer. OOM Killer’ın geçmişine bakmak swap sorunlarını teşhiste çok yardımcı olur:

# OOM Killer aktivitelerini kontrol et
sudo dmesg | grep -i "oom|killed process|out of memory"

# journalctl ile daha detaylı
sudo journalctl -k | grep -i "oom|killed"

# Belirli bir sürecin OOM score'unu görme
cat /proc/$(pgrep nginx)/oom_score
cat /proc/$(pgrep nginx)/oom_score_adj

# Kritik servislerin OOM Killer tarafından öldürülmesini engelle
echo -1000 | sudo tee /proc/$(pgrep sshd)/oom_score_adj

OOM score değeri ne kadar yüksekse o süreç OOM Killer tarafından o kadar erken hedef alınır. -1000 değeri süreci neredeyse dokunulmaz yapar, ancak bunu sadece gerçekten kritik servisler için yapın.

Çoklu Swap Alanı Yönetimi

Bazı durumlarda birden fazla swap alanı kullanmak gerekebilir. Öncelik sırası ayarlamak önemli:

# Mevcut swap alanlarını öncelik sırasıyla listele
swapon --show

# Yüksek hızlı SSD'ye yeni swap ekle (öncelik: 10)
sudo swapon /dev/nvme0n1p3 -p 10

# Yavaş HDD swap (öncelik: 5)
sudo swapon /swapfile -p 5

# fstab'da öncelik tanımlama
# /dev/nvme0n1p3 none swap sw,pri=10 0 0
# /swapfile      none swap sw,pri=5  0 0

# Tüm swap'ları devre dışı bırak
sudo swapoff -a

# Tüm swap'ları aktif et (fstab'dan)
sudo swapon -a

Öncelik değeri yüksek olan swap alanı önce dolar. Hızlı SSD’ye yüksek öncelik vererek performansı artırabilirsiniz.

Performans İyileştirme: Gerçek Dünya Örneği

Bir e-ticaret müşterisinin MySQL sunucusunda yaşanan senaryo: 16GB RAM, swap yok, gece yarısı büyük raporlama sorguları sırasında OOM Killer MySQL’i öldürüyor.

Uygulanan çözüm adımları:

# 1. Acil: 8GB swap dosyası oluştur
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 2. MySQL için düşük swappiness (veritabanları için kritik)
sudo sysctl vm.swappiness=1
echo 'vm.swappiness=1' | sudo tee -a /etc/sysctl.conf

# 3. MySQL için OOM score ayarla
MYSQL_PID=$(pgrep mysqld)
echo -500 | sudo tee /proc/$MYSQL_PID/oom_score_adj

# 4. MySQL'in bellek kullanımını optimize et
# /etc/mysql/mysql.conf.d/mysqld.cnf içinde:
# innodb_buffer_pool_size = 10G  (RAM'in ~%60-70'i)
# innodb_buffer_pool_instances = 8

# 5. Kalıcı fstab kaydı
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Sonuç: OOM sorunları tamamen ortadan kalktı, swap kullanımı stres dönemlerinde 2-3GB’a çıkıyor ancak sistem stabil kalıyor.

Sistem Yeniden Başlatıldıktan Sonra Doğrulama

# Boot sonrası swap kontrolü için bir test scripti
cat << 'EOF' | sudo tee /usr/local/bin/check_swap.sh
#!/bin/bash
echo "=== Swap Durumu ==="
swapon --show
echo ""
echo "=== Bellek Özeti ==="
free -h
echo ""
echo "=== Kernel Parametreleri ==="
sysctl vm.swappiness vm.vfs_cache_pressure
echo ""
echo "=== Swap Kullanan Top 5 Süreç ==="
for pid in /proc/[0-9]*; do
    pid_num=$(basename $pid)
    swap=$(grep VmSwap "$pid/status" 2>/dev/null | awk '{print $2}')
    if [ -n "$swap" ] && [ "$swap" -gt 0 ] 2>/dev/null; then
        name=$(cat "$pid/comm" 2>/dev/null)
        echo "$swap $pid_num $name"
    fi
done | sort -rn | head -5 | awk '{printf "%d MB - PID: %s - %sn", $1/1024, $2, $3}'
EOF

sudo chmod +x /usr/local/bin/check_swap.sh
sudo /usr/local/bin/check_swap.sh

Sonuç

Swap yönetimi, Linux sistem yönetiminin en temel ama en çok ihmal edilen konularından biri. Özet olarak kritik noktalara değinelim:

  • Swap boyutu için eski “RAM’in 2 katı” kuralı artık geçerliliğini yitirdi. Sunucu kullanım profiline göre 2-8GB arası genellikle yeterli, ancak hibernation kullanacaksanız RAM kadar swap gerekli.
  • swappiness=10 değeri çoğu sunucu için ideal başlangıç noktası. Veritabanı sunucularında 1’e kadar düşürebilirsiniz.
  • Swap dosyası kullanmak, partition’a göre çok daha esnek yönetim sağlıyor. Bulut ortamlarında kesinlikle swap dosyasını tercih edin.
  • İzleme olmadan swap yönetimi eksik kalır. En azından basit bir cron scriptiyle swap kullanımını takip edin.
  • OOM Killer loglarını düzenli kontrol edin, kritik servisler öldürülüyorsa hem swap’ı artırın hem de OOM score’ları düzenleyin.
  • ZRAM disk I/O’sunun dar boğaz olduğu sistemlerde swap performansını dramatik biçimde artırabilir.

Swap sorunları genellikle anlık krizlerde fark edilir, ancak proaktif izleme ve doğru yapılandırmayla bu krizleri büyük ölçüde önleyebilirsiniz. Sisteminizin bellek kullanım profilini iyi tanıyın ve swap ayarlarınızı buna göre optimize edin.

Bir yanıt yazın

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