Yüksek Bekleme Süresi Sorunları: Linux’ta iowait Analizi

Sunucunuz aniden yavaşlamaya başladı, uygulamalar cevap vermez oldu ve top komutunu açtığınızda CPU kullanımı düşük görünmesine rağmen sistem bir türlü toparlanamıyor. İşte bu klasik iowait senaryosu, her sistem yöneticisinin er ya da geç karşılaştığı ve çözmeye çalıştığı bir kabustur. Bu yazıda iowait’in ne olduğunu, nasıl analiz edileceğini ve gerçek dünya senaryolarında nasıl çözüleceğini adım adım ele alacağız.

iowait Nedir ve Neden Önemlidir?

iowait, CPU’nun bir I/O işleminin tamamlanmasını beklerken geçirdiği sürenin yüzdesidir. Linux çekirdeği bu değeri, işlemcinin disk, ağ veya başka bir I/O kaynağından gelen yanıtı beklerken “boşta” saydığı zamanı temsil etmek için kullanır. Ancak buradaki kritik nokta şudur: iowait yüksek olduğunda CPU teknik olarak boşta görünür ama aslında hiçbir iş yapamaz durumdadır.

Peki ne zaman alarm vermelisiniz? Genel kabul görmüş eşik değerleri şöyledir:

  • %0-10: Normal, endişelenmeye gerek yok
  • %10-25: Dikkat edilmeli, trend takibi yapılmalı
  • %25-50: Ciddi performans sorunu, müdahale gerekebilir
  • %50+: Kritik durum, acil müdahale şart

Bu değerler tabii ki sisteme ve iş yüküne göre değişir. Bir veritabanı sunucusu için %15 iowait normal olabilirken, bir web sunucusu için %8 bile sorun işareti olabilir.

Temel Araçlarla İlk Tespit

top ve htop ile Hızlı Bakış

Sorun yaşadığınızda ilk açacağınız araç büyük ihtimalle top olacak. Ama çoğu kişi iowait değerini gözden kaçırıyor.

top

top çıktısının üst kısmındaki CPU satırına bakın:

%Cpu(s):  2.3 us,  0.8 sy,  0.0 ni, 45.2 id, 48.1 wa,  0.0 hi,  3.6 si,  0.0 st

Burada wa değeri iowait’i gösterir. Yukarıdaki örnekte %48.1 iowait var ki bu ciddi bir durum. id ise idle (boşta) değeridir.

Çok çekirdekli sistemlerde her çekirdek için ayrı değer görmek isterseniz top içinde 1 tuşuna basın. Bu size hangi çekirdeğin daha fazla beklediğini gösterir ve sorunun tek bir diskle mi yoksa genel sistemle mi ilgili olduğunu anlamanıza yardımcı olur.

vmstat ile Anlık ve Periyodik İzleme

vmstat bu tür analizler için çok güçlü bir araç. Basit kullanımı şu şekilde:

# Her 2 saniyede bir, 10 kez çıktı al
vmstat 2 10

Çıktı şöyle görünür:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  8      0 245780  12340 891240    0    0  8234   445  892 1203  2  1 45 52  0
 2  7      0 243120  12340 891240    0    0  9120   312  945 1289  3  1 42 54  0

Burada dikkat etmeniz gereken sütunlar:

  • b: Engellenmiş (blocked) process sayısı, yüksekse sorun var
  • bi: Diskten okunan blok sayısı (blocks in)
  • bo: Diske yazılan blok sayısı (blocks out)
  • wa: iowait yüzdesi

b sütununda yüksek değerler görüyorsanız, bu processler I/O bekliyor demektir.

iostat ile Disk Bazlı Analiz

sysstat paketinin parçası olan iostat, disk I/O sorunlarını derinlemesine analiz etmek için vazgeçilmez araçtır.

# sysstat paketini yükle (Debian/Ubuntu)
apt install sysstat

# Her 2 saniyede bir çıktı, genişletilmiş bilgi
iostat -x 2 5

Çıktıdan şu sütunlara odaklanın:

  • %util: Disk kullanım yüzdesi. %100’e yaklaşıyorsa disk doymuş demektir
  • await: Ortalama I/O bekleme süresi (milisaniye)
  • r_await ve w_await: Okuma ve yazma için ayrı ayrı bekleme süreleri
  • svctm: Servis süresi (await’ten büyükse sorun var)
  • rrqm/s ve wrqm/s: Birleştirilen istek sayısı
# Sadece belirli bir disk için izleme
iostat -x -d sda 1 30

# JSON formatında çıktı (monitoring sistemlerine entegrasyon için)
iostat -x -o JSON 2 5

Derinlemesine Analiz Araçları

iotop ile Process Bazlı İzleme

Hangi processın en çok I/O yaptığını bulmak için iotop mükemmeldir:

# iotop kurulumu
apt install iotop

# Sadece aktif I/O yapan processleri göster
iotop -o

# Batch modunda çalıştır (log için kullanışlı)
iotop -b -n 5 -d 2

iotop çıktısında şunlara bakın:

  • DISK READ / DISK WRITE: Anlık okuma/yazma hızı
  • SWAPIN: Swap’tan okuma yüzdesi
  • IO: Toplam I/O bekleme yüzdesi

Eğer iotop komutu yoksa veya kernel desteği yetersizse alternatif olarak pidstat kullanabilirsiniz:

# Her process için I/O istatistikleri
pidstat -d 2 10

# Belirli bir PID için
pidstat -d -p 1234 2 10

lsof ile Açık Dosya ve Disk İlişkisi

Bir process neden bu kadar I/O yapıyor sorusunu yanıtlamak için lsof çok işe yarar:

# En çok I/O yapan processi bulduktan sonra hangi dosyalara eriştiğine bak
lsof -p <PID>

# Belirli bir diskteki açık dosyaları listele
lsof /dev/sda1

# Silinmiş ama hala açık olan dosyaları bul (disk doluysa bu kritik!)
lsof | grep deleted

Silinmiş ama açık dosyalar çok sinsi bir sorundur. Log rotation yanlış yapılandırılmışsa veya bir uygulama çöktüğünde dosyaları kapatmazsa, disk alanı dolabilir ama df size alanın dolu olduğunu göstermeyebilir.

blktrace ile Gelişmiş Blok Seviyesi Analiz

Gerçekten derinlemesine bir analiz yapmak istiyorsanız blktrace ve blkparse ikilisine ihtiyacınız olacak:

# blktrace kurulumu
apt install blktrace

# sda diski için 30 saniye kayıt al
blktrace -d /dev/sda -o trace_output -w 30

# Kayıtları analiz et
blkparse -i trace_output.blktrace.* -o parsed_output.txt

# btt ile istatistik çıkar
btt -i trace_output.blktrace.*

Bu araç size I/O isteklerinin tam zaman çizelgesini verir. Özellikle “scheduling delay” yani kernel I/O scheduler’ın eklediği gecikme ile gerçek disk gecikmesini birbirinden ayırt edebilirsiniz.

Gerçek Dünya Senaryoları

Senaryo 1: MySQL Veritabanı Sunucusu Çöküşü

Bir e-ticaret şirketinin MySQL sunucusu gece yarısı aniden yavaşladı. Sabah erkenden çağrıldığımda iowait %78’deydi.

# İlk tespit
vmstat 1 10
iostat -x 1 10
iotop -o -b -n 3

iotop çıktısı MySQL’i işaret ediyordu. Sonraki adım:

# MySQL slow query log'u kontrol et
tail -f /var/log/mysql/slow-query.log

# Anlık çalışan sorguları gör
mysql -e "SHOW PROCESSLISTG" | grep -i "state"

# InnoDB I/O durumu
mysql -e "SHOW ENGINE INNODB STATUSG" | grep -A 20 "FILE I/O"

Sorun, geceleri çalışan bir rapor sorgusunun tam tablo taraması yapmasıydı. Index’siz bir WHERE koşulu yüzünden milyonlarca satır okunuyordu. Çözüm index eklemek oldu ama geçici çözüm olarak sorguyu durdurduk:

# Sorunu yaratan connection'ı bul ve öldür
mysql -e "SHOW PROCESSLISTG" | grep -B 5 "Copying to tmp table"
mysql -e "KILL QUERY <connection_id>;"

Senaryo 2: Log Yazma Sorunu ve Disk Doluluğu

Bir uygulama sunucusunda iowait %35’e çıkmıştı. iostat çıktısına baktığımda write operasyonları son derece yoğundu.

# En fazla yazan processleri bul
iotop -o -a -b -n 5

# Hangi dizine yazıldığını bul
inotifywait -m -r /var/log/ --format '%T %w %f %e' --timefmt '%H:%M:%S'

Bir uygulama her HTTP isteği için ayrı bir debug log satırı yazıyordu ve production’da debug log kapatılmamıştı. Saniyede binlerce satır yazılıyordu.

# Log yazma hızını kontrol et
watch -n 1 "ls -la /var/log/app/ | tail -5"

# Gerçek zamanlı dosya boyutu değişimini izle
watch -n 1 "du -sh /var/log/app/"

Çözüm log seviyesini INFO‘ya almak ve logrotate yapılandırmasını düzeltmek oldu. Ayrıca uygulamayı asenkron logging kullanacak şekilde yapılandırdık.

Senaryo 3: NFS Mount Kaynaklı iowait

Bu senaryo biraz daha sinsi. Sunucuda iowait yüksekti ama iostat yerel disklerde bir sorun göstermiyordu.

# NFS mount'ları kontrol et
mount | grep nfs

# NFS istatistikleri
nfsstat -c

# NFS I/O'yu izle
iostat -x -d nfs* 2 10
# NFS sunucusuna bağlantı testi
showmount -e nfs-server-ip

# NFS performans testi
dd if=/dev/zero of=/mnt/nfs/test bs=1M count=100 oflag=direct

NFS sunucusunun ağ bağlantısında paket kaybı vardı. ping testleri bunu ortaya koydu. Çözüm NFS mount seçeneklerini düzenlemek ve ağ sorununu gidermekti:

# /etc/fstab'da NFS mount seçeneklerini optimize et
# nfs-server:/share /mnt/nfs nfs rsize=8192,wsize=8192,timeo=14,intr,soft 0 0

I/O Performansını İyileştirme Yöntemleri

I/O Scheduler Seçimi

Linux’ta farklı I/O scheduler’lar vardır ve doğru seçim performansı ciddi ölçüde etkiler:

# Mevcut scheduler'ı öğren
cat /sys/block/sda/queue/scheduler

# Scheduler değiştir (geçici)
echo mq-deadline > /sys/block/sda/queue/scheduler

# SSD için none (noop) veya mq-deadline önerilir
echo none > /sys/block/sda/queue/scheduler

# HDD için bfq veya mq-deadline
echo bfq > /sys/block/sda/queue/scheduler

Kalıcı yapmak için /etc/udev/rules.d/60-io-scheduler.rules dosyası oluşturun:

# SSD'ler için none scheduler
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"

# HDD'ler için bfq scheduler
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"

Read-Ahead Ayarları

# Mevcut read-ahead değerini gör (512 byte cinsinden)
blockdev --getra /dev/sda

# Sequential okuma ağırlıklı sistemlerde artır
blockdev --setra 4096 /dev/sda

# Kalıcı yapmak için rc.local veya udev kuralı kullan

vm.dirty Parametrelerinin Optimizasyonu

Kernel’in dirty page (yazılmayı bekleyen sayfa) yönetimi iowait’i doğrudan etkiler:

# Mevcut değerleri gör
sysctl vm.dirty_ratio
sysctl vm.dirty_background_ratio
sysctl vm.dirty_expire_centisecs

# Veritabanı sunucusu için optimize edilmiş değerler
cat >> /etc/sysctl.d/99-io-performance.conf << EOF
# Dirty page yüzdesi - bu seviyeye ulaşınca yazma başlar
vm.dirty_background_ratio = 5
# Bu seviyede process'ler yazma işlemi için bloklanır
vm.dirty_ratio = 15
# Dirty page'lerin maksimum yaşı (centisaniye)
vm.dirty_expire_centisecs = 1500
# Writeback thread ne kadar sıklıkla çalışsın
vm.dirty_writeback_centisecs = 500
EOF

sysctl -p /etc/sysctl.d/99-io-performance.conf

Swap Kullanımını Azaltma

iowait bazen disk sorunu değil, swap thrashing’den kaynaklanır:

# Swap kullanımını kontrol et
free -h
vmstat -s | grep swap

# Swappiness değerini düşür (varsayılan 60)
sysctl vm.swappiness=10
echo "vm.swappiness=10" >> /etc/sysctl.d/99-performance.conf

# Hangi processler swap kullanıyor
for pid in /proc/[0-9]*/status; do
  awk '/VmSwap|Name/{printf $2 " " $3}END{print ""}' $pid
done | sort -k3 -n -r | head -20

Sürekli İzleme için Script Hazırlama

Tek seferlik analizin ötesine geçmek ve trend takibi yapmak için basit bir monitoring scripti hazırlayalım:

#!/bin/bash
# iowait_monitor.sh - Yüksek iowait tespiti ve loglama

THRESHOLD=25
LOG_FILE="/var/log/iowait_monitor.log"
ALERT_EMAIL="[email protected]"

log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}

get_iowait() {
    # vmstat çıktısından iowait değerini al
    vmstat 1 3 | tail -1 | awk '{print $16}'
}

collect_diagnostics() {
    local timestamp=$(date '+%Y%m%d_%H%M%S')
    local diag_file="/tmp/iowait_diag_${timestamp}.txt"

    {
        echo "=== iowait Diagnostic Report ==="
        echo "Time: $(date)"
        echo ""
        echo "=== vmstat ==="
        vmstat 1 5
        echo ""
        echo "=== iostat ==="
        iostat -x 1 3
        echo ""
        echo "=== Top I/O Processes ==="
        iotop -b -n 2 -o 2>/dev/null || pidstat -d 1 3
        echo ""
        echo "=== Disk Usage ==="
        df -h
    } > "$diag_file"

    echo "$diag_file"
}

while true; do
    IOWAIT=$(get_iowait)

    if [ "$IOWAIT" -gt "$THRESHOLD" ]; then
        log_message "ALERT: iowait %${IOWAIT} - Threshold: %${THRESHOLD}"
        DIAG_FILE=$(collect_diagnostics)
        log_message "Diagnostics saved: $DIAG_FILE"

        # Mail gönder (mailutils kurulu olmalı)
        if command -v mail &>/dev/null; then
            mail -s "iowait Alert: %${IOWAIT} on $(hostname)" 
                 -a "Content-Type: text/plain" 
                 "$ALERT_EMAIL" < "$DIAG_FILE"
        fi
    fi

    sleep 30
done

Bu scripti systemd service olarak çalıştırabilirsiniz:

# /etc/systemd/system/iowait-monitor.service
[Unit]
Description=iowait Monitor Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/iowait_monitor.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now iowait-monitor

Hızlı Tanı için Kontrol Listesi

Bir sunucuda yüksek iowait gördüğünüzde şu sırayı takip edin:

  • Adım 1: vmstat 1 10 ile genel durumu değerlendirin, b sütununu kontrol edin
  • Adım 2: iostat -x 1 5 ile hangi diskin sorunlu olduğunu belirleyin, %util ve await değerlerine bakın
  • Adım 3: iotop -o ile hangi process’in I/O yaptığını bulun
  • Adım 4: lsof -p ile sorunlu process’in hangi dosyalara eriştiğini görün
  • Adım 5: df -h ve du -sh /* ile disk doluluk durumunu kontrol edin
  • Adım 6: dmesg | grep -i error | tail -50 ile donanım hatası olup olmadığına bakın
  • Adım 7: smartctl -a /dev/sda ile disk sağlığını kontrol edin

Disk Sağlığı Kontrolü

iowait sorunlarının bir bölümü bozulmakta olan disklerden kaynaklanır. Bunu es geçmeyin:

# smartmontools kurulumu ve disk sağlık testi
apt install smartmontools

# Disk sağlık özeti
smartctl -H /dev/sda

# Detaylı SMART verileri
smartctl -a /dev/sda | grep -E "Reallocated|Pending|Uncorrectable|Temperature"

# Kernel disk hatalarını kontrol et
dmesg | grep -iE "error|failed|reset|timeout" | grep -i "sd[a-z]" | tail -20

Eğer Reallocated_Sector_Ct değeri sıfırdan büyükse, disk bozulmaya başlıyor demektir ve en kısa sürede değiştirilmesi gerekir.

Sonuç

iowait analizi, Linux sistem yönetiminin en karmaşık ve aynı zamanda en tatmin edici alanlarından biridir. Sorunun bir boyutunu çözdüğünüzde bazen başka bir katman ortaya çıkabilir; disk sorunlu görünürken aslında NFS ağ gecikmesi, MySQL sorunu görünürken aslında eksik index sorunuyla karşılaşabilirsiniz.

Buradaki en önemli ders şudur: iowait tek başına bir sorun değil, bir semptomdur. Gerçek sorunu bulmak için katmanlı analiz yapmanız gerekir. vmstat ile genel resmi görün, iostat ile diski tespit edin, iotop ile process’i bulun, lsof ile dosyaya inin.

İkinci önemli nokta ise proaktif izlemedir. Sorun yaşandıktan sonra koşmak yerine, trend verilerini toplayın. Prometheus ve Grafana ile node_exporter’ı entegre ederseniz iowait değerlerini zaman içinde görebilir ve anomalileri önceden tespit edebilirsiniz. Bir disk bozulmadan önce size uyarı vermeye başlar, bir sorgu yavaşlamadan önce pattern değişikliğini fark edersiniz.

Son olarak, üretim sistemlerinde değişiklik yapmadan önce her zaman bir plan ve geri alma stratejiniz olsun. I/O scheduler değiştirmek veya kernel parametrelerini düzenlemek beklenmedik sonuçlar doğurabilir. Test ortamında deneyin, metrikleri karşılaştırın, sonra üreteme taşıyın.

Similar Posts

Bir yanıt yazın

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