Acil serviste nöbetçi olduğunuz bir gece, koridordan bir çığlık yükselir. Genç bir adam, sağ kolunu göğsüne bastırmış, sol eliyle bileğini tutarak içeri koşar. Gözlerinden yaşlar boşanmaktadır: "Doktor bey yetişin, kolum koptu! Kemiklerim un ufak oldu, içeride hiçbir şey kalmadı, felç kaldım!"
Deneyimli bir ortopedist veya acil tıp uzmanı hastaya bakar, omzun normal yuvarlak hatlarının kaybolduğunu ve "apolet belirtisi" verdiğini görür. Teşhis açıktır: Omuz çıkığı (anterior glenohumeral dislokasyon). Kolda ne bir kopma vardır, ne de kemikler un ufak olmuştur. Kemik sapasağlamdır; sadece eklem yuvasından (glenoid kavite) birkaç santimetre dışarı kaymıştır ve kas spazmı yüzünden kilitlenmiştir. Hekim hastayı sedyeye yatırır, kolu hafifçe çeker (traksiyon) ve dışa doğru nazikçe çevirir (Kocher manevrası). Odada hafif bir "klik" sesi duyulur. Kemik yuvasına oturmuştur. Bir saniye önce felç olduğunu haykıran hastanın yüzündeki o dehşet anında silinir, kolunu oynatmaya başlar ve mahcup bir tebessümle doktora bakar.
Veritabanı yönetimi ve web altyapılarında da sistem yöneticilerinin sık sık karşılaştığı en dramatik krizlerden biri, tek bir veritabanı tablosunun disloke olması (crash durumu) sonucu müşterinin yaşadığı o kıyamet hezeyanıdır.
Pazartesi 09:30: "Veritabanı Bağlantısı Kurulamıyor"
Olay genellikle tipik bir WordPress veya özel yazılım çalıştıran bir e-ticaret sitesinde patlak verir. Gece yarısı sunucuda anlık bir bellek tükenmesi (OOM Killer devreye girmiştir), elektrik dalgalanması sonrası veritabanı servisinin zorla kapanması (hard kill) veya disk I/O operasyonlarının kilitlenmesi yaşanmıştır.
Sabah mesaisi başladığında site sahibi tarayıcısını açar ve o meşhur siyah beyaz ölüm ekranıyla karşılaşır:
"Error establishing a database connection" (Veritabanı bağlantısı kurulurken hata oluştu)
Site sahibi yönetim paneline (/wp-admin) girmeyi dener; yine aynı hata. phpMyAdmin'e girer, veritabanı adının yanında kırmızı bir ünlem işareti görür veya tablolara tıkladığında ekranda şu uyarı belirir:
SQL Error (145): Table './firma_wp/wp_options' is marked as crashed
and should be repairedKullanıcının zihninde o an dünyalar yıkılır. SQL hata kodundaki crashed (çöktü/hasar gördü) kelimesini görür görmez beynindeki panik merkezi amigdala alev alır. Kullanıcı için "çöktü" demek, "buharlaştı, yok oldu, silindi" demektir.
Destek Masasında Ecel Terleri
Destek biletlerine saniyede 4 adet bilet düşmeye başlar. Müşterinin açtığı biletlerin başlıkları acil servisteki omuz çıkığı feryadından farksızdır:
"ACİL! YARDIM EDİN! BÜTÜN VERİTABANIM SİLİNMİŞ!"
"15 YILLIK ŞİRKET ARŞİVİMİZ YOK OLDU! BİZE KİM SALDIRDI?"
"DERHAL DÜNKÜ YEDEĞİ GERİ YÜKLEYİN YOKSA İNTİHAR EDECEĞİM!"
Müşteri telefon santralini de kilitler. Telefonda ağlamaklı bir sesle şirketin tüm müşteri kayıtlarının, ürün stoklarının ve siparişlerinin silindiğini, firmanın iflasın eşiğinde olduğunu haykırır. Ona göre gece karanlık eller sunucuya sızmış ve DROP DATABASE komutuyla bütün veriyi uzaya fırlatmıştır.
"REPAIR TABLE": Ortopedik Redüksiyonun Dijital Kopyası
Sistem mühendisi terminali açar. MySQL/MariaDB sunucusuna SSH üzerinden root olarak bağlanır:
mysql -u root -p
USE firma_wp;
CHECK TABLE wp_options;Çıktı durumu netleştirir:
+----------------------+-------+----------+-------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+----------------------+-------+----------+-------------------------------------------------------+
| firma_wp.wp_options | check | error | Size of datafile does not match indexfile; is crashed |
+----------------------+-------+----------+-------------------------------------------------------+Veritabanı silinmemiştir! Tablo oradadır, veriler disktedir. Sadece ani kapanma yüzünden veri dosyasının boyutu ile indeks dosyasının (.MYI veya InnoDB tablespace kayıtları) son durumu arasındaki işaretçi (pointer) uyuşmazlığı oluşmuştur. Tıpkı omuz kemiğinin yuvasından çıkması gibi, indeks ağacı eklem yerinden oynamıştır.
Mühendis terminale o sihirli ortopedik manevra komutunu yazar:
REPAIR TABLE wp_options;Veya konsoldan:
myisamchk -r -q /var/lib/mysql/firma_wp/wp_options.MYIEkranda birkaç milisaniye içinde şu çıktı belirir:
+----------------------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------------------+--------+----------+----------+
| firma_wp.wp_options | repair | status | OK |
+----------------------+--------+----------+----------+Sistem yöneticisi tarayıcıdan müşterinin web sitesine tıklar. Sayfa 0.4 saniyede, tüm görselleriyle, slider'larıyla ve ürünleriyle şak diye açılır. Olayın başından sonuna geçen süre 45 saniyedir.
Destek masasına yazılan kısa yanıt: "Ahmet Bey, sistemde herhangi bir veri kaybı yaşanmamıştır. wp_options tablonuzdaki geçici indeks kayması onarılmıştır. Siteniz yayındadır, iyi çalışmalar dileriz."
Hattın diğer ucundaki o kıyamet koparan müşteriden gelen yanıt ise her zamanki gibi mahcup ve şaşkındır: "Aaa, gelmiş... Çok teşekkürler, biz de silindi sandık korktuk."
MyISAM Mirasından Modern InnoDB Mimarisine
Bu "tablo çıkığı" sendromu, çoğunlukla eski nesil MyISAM depolama motorunun (storage engine) mirasıdır. MyISAM mimarisinde veriler (.MYD) ile indeksler (.MYI) ayrı dosyalarda tutulur ve işlem güvenliği (ACID uyumluluğu, transactions) yoktur. Sunucu ani kapandığında indeks dosyası bozulmaya son derece meyillidir.
Oysa modern InnoDB motoru, bu tür senaryolar için geliştirilmiş güçlü bir savunma mekanizmasına sahiptir:
- Write-Ahead Logging (WAL): Veriler diske yazılmadan önce
ib_logfile(redo log) alanına kaydedilir. - Crash Recovery: Sunucu yeniden başladığında InnoDB otomatik olarak logları tarar, tamamlanmamış işlemleri geri alır (rollback) ve diske yazılmamış işlemleri tamamlar (redo).
- innodb_force_recovery: Çok ağır bozulmalarda bile 1'den 6'ya kadar seviyelerle veritabanı salt-okunur modda ayağa kaldırılıp veriler
mysqldumpile kurtarılabilir.
Buna rağmen hâlâ piyasada MyISAM motoruyla çalışan yüz binlerce eski veritabanı bulunmakta ve bu tablolar her ani yükte sistem yöneticilerine acil servis nöbeti yaşatmaktadır.
Kriz Anında Soğukkanlılık Reçetesi
Bir veritabanı hatasıyla karşılaştığınızda kıyamet senaryoları yazmadan önce uygulanması gereken altın kurallar şunlardır:
- Hata Mesajını Dikkatle Okuyun: "Connection refused" servis durdu demektir; "Table crashed" indeks bozuldu demektir; "Access denied" şifre yanlış demektir. Hiçbiri "Verileriniz silindi" anlamına gelmez.
- MyISAM Tablolarını InnoDB'ye Dönüştürün:
ALTER TABLE tablo_adi ENGINE=InnoDB;komutuyla eski tablolarınızı modern, çökmeye dayanıklı motora geçirin. - Yedekten Önce Mevcut Durumu Koruyun: Panikle eski bir yedeği doğrudan geri yüklemeyin! Eski yedeği yüklerseniz, son 3 gündür sitenize gelen gerçek siparişleri ve yeni kullanıcıları kendi elinizle silmiş olursunuz. Önce mevcut bozuk veritabanının fiziksel bir kopyasını alın.
- Otomatik Onarım Tanımları: WordPress kullanıyorsanız
wp-config.phpdosyasına geçici olarakdefine('WP_ALLOW_REPAIR', true);satırını ekleyip/wp-admin/maint/repair.phpadresinden tek tıkla tabloları onarabilirsiniz.
Bilgisizlik panik doğurur; panik ise yanlış kararlara yol açar. Tıpta nasıl her kol ağrısı ampütasyon gerektirmiyorsa, veritabanındaki her çökme hatası da felaket değildir. Çoğu zaman gereken şey panikle bağırmak değil, doğru manevrayla o disloke olmuş tabloyu yuvasına oturtmaktır.