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