Büyük bir metropol devlet hastanesinin acil servis kapısını gözünüzün önüne getirin. Cuma gecesi saat 22:00; trafik kazaları, kalp krizleri ve astım krizleri peş peşe acile getirilmektedir. Şimdi hastane yönetiminin kapıya çok tuhaf, ucube bir mekanizma kurduğunu hayal edin: Acil servisin girişinde sadece tek bir döner kapı vardır. Ve bu kapının kuralı şudur: Bir sedye kapıdan içeri girdiği anda, içerideki hastanın kaydı tamamlanıp sedye koridordan çıkana kadar o döner kapı kilitlenir! Dışarıda bekleyen diğer 40 sedye, kanaması olan hastalar, içeriye girmek isteyen nöbetçi hekimler kapının önünde çaresizce beklemek zorundadır. İçerideki tek bir hastanın pansumanı yapılırken dışarıdaki kalp krizi vakası kapı önünde nefessiz kalarak hayatını kaybeder.
Kulağa tam bir akıl tutulması gibi geliyor, değil mi? Oysa veritabanı mühendisliğinde ve e-ticaret sitelerinde her Black Friday veya kampanya döneminde sistemleri komaya sokan arıza, tam olarak bu tek kapılı kilitlenme faciasıdır: MySQL tablolarının modern 'InnoDB' yerine arkaik 'MyISAM' depolama motorunda unutulması.
Efsane Cuma: Reklamlar Açıldı, Sunucu Dondu
Bir e-ticaret markası haftalardır televizyonlarda ve sosyal medyada büyük bir indirim kampanyasının duyurusunu yapmaktadır: "Bu akşam saat 21:00'de tüm ürünlerde %50 indirim!"
Şirket sunucu masrafından kaçınmamış, 32 çekirdekli, 128 GB RAM'li devasa bir sunucu kiralamıştır. Sunucunun işlemcisi boştadır, diskleri kurumsal NVMe'dir. Saat 21:00 olduğunda siteye aynı anda 10.000 kişi hücum eder.
Müşteriler ürünleri sepete atar, ödeme butonuna tıklar. Ve tam o anda sistem bir duvara toslar.
Sepet sayfası dönmeye başlar... 10 saniye, 30 saniye, 60 saniye... Ve ekranda o soğuk, ölümcül veritabanı kopma hatası patlar:
SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
(Veritabanı sunucusu zaman aşımına uğradı ve bağlantıyı kopardı!)
Sitenin ana sayfası bile açılmaz hale gelir. Şirketin genel müdürü, e-ticaret direktörü ve sunucu yöneticisi birbirine girer: "128 GB RAM aldık, bu sunucu neden çöktü? Bize kim saldırıyor?"
Table-Level Lock vs. Row-Level Lock: İki Dünyanın Savaşı
Sistem yöneticisi SSH ile veritabanı sunucusuna bağlanır ve o meşhur sorgu izleme komutunu çalıştırır:
SHOW FULL PROCESSLIST;Ekrana dökülen yüzlerce satır, kapıda yığılmış sedyelerin otopsisidir:
Id: 4821 | User: eticaret | Command: Query | Time: 48 | State: Locked |
Info: UPDATE wp_posts SET post_modified = NOW() WHERE ID = 142
Id: 4822 | User: eticaret | Command: Query | Time: 47 | State: Locked |
Info: SELECT * FROM wp_posts WHERE ID = 841
Id: 4823 | User: eticaret | Command: Query | Time: 47 | State: Locked |
Info: SELECT * FROM wp_posts WHERE ID = 920
... (Yüzlerce sorgu "Locked" durumunda beklemektedir!)Tablo kilitlenmiştir! Peki neden?
Çünkü sitenin wp_posts (veya sipariş) tablosu, 2010 yılından kalma eski bir veritabanı dökümünden içeri aktarılmış ve depolama motoru (Storage Engine) MyISAM olarak kalmıştır!
MySQL dünyasında iki temel motor vardır ve aralarındaki fark yaşam ile ölüm arasındaki farktır:
1. MyISAM (Tablo Seviyesinde Kilitlenme - Table-Level Locking)
MyISAM, 90'lı yıllarda disklerin yavaş olduğu dönemde sadece okuma (SELECT) hızına odaklanarak tasarlanmış ilkel bir motordur. Bir kullanıcı siteden bir ürün satın aldığında veya stoğu güncellediğinde (UPDATE / INSERT), MyISAM o tablonun tamamına kilit vurur!
O anda o tablodan ürün okumaya çalışan diğer 500 müşterinin SELECT sorgusu kapıda bekletilir. Yazma işlemi bitmeden hiç kimse o tablodan tek bir harf bile okuyamaz! Yazma sorguları ardı ardına kuyruğa girdikçe, kuyruk patlar, veritabanı hafızası kilitlenir ve MySQL nefessiz kalarak tüm bağlantıları kapatır (has gone away).
2. InnoDB (Satır Seviyesinde Kilitlenme - Row-Level Locking)
2010'lu yıllardan itibaren MySQL'in resmi varsayılanı olan InnoDB ise tam teşekküllü, modern bir cerrahi kapıdır. Bir müşteri 142 nolu ürünü satın aldığında, InnoDB tablonun tamamını değil; sadece ve sadece o 142 nolu satırı kilitler!
Aynı saniyede 841 nolu ürünü inceleyen diğer müşteri hiçbir gecikme yaşamadan veriyi okur, üçüncü müşteri 920 nolu ürünü satın alır. Herkes kendi şeridinde, kimse kimseyi beklemeden akar. Üstelik InnoDB tam bir işlem güvenliğine (ACID - Atomicity, Consistency, Isolation, Durability) sahiptir; elektrik kesilse bile veritabanı bozulmaz.
Tek Bir Komutla Gelen Kurtuluş
Sistem yöneticisi durumu anlar. Kampanyanın ortasında, canlı veritabanında o cerrahi neşteri vurur:
-- Kilitlenen MyISAM tablolarını modern InnoDB motoruna dönüştür:
ALTER TABLE wp_posts ENGINE = InnoDB;
ALTER TABLE wp_postmeta ENGINE = InnoDB;
ALTER TABLE wp_options ENGINE = InnoDB;Komut çalışır, MySQL tabloları satır seviyesinde kilitlenen modern InnoDB mimarisine dönüştürür.
Ve birkaç saniye içinde o kilitlenen kuyruk bir baraj kapağının açılması gibi boşalır. İşlemci yükü 80'den 4'e geriler. Saniyede yüzlerce sipariş tıkır tıkır veritabanına yazılmaya başlar; kasaya dakikalar içinde yüz binlerce liralık ciro akar.
Veritabanı Mimarisi Reçetesi
E-ticaret ve yüksek trafikli sistemlerde MyISAM kalıntılarını temizlemek ve veritabanını bir yarış arabasına dönüştürmek için şu adımlar şarttır:
- Eski Tablo Taraması: Veritabanınızda hâlâ MyISAM kalıntısı olup olmadığını şu SQL sorgusuyla derhal tespit edin:
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'veritabani_adiniz' AND engine = 'MyISAM'; - Toplu Dönüşüm: Çıkan tüm MyISAM tablolarını tek tek
ALTER TABLE ... ENGINE = InnoDB;komutuyla dönüştürün. innodb_buffer_pool_sizeOptimizasyonu: InnoDB'nin gücü bellekten gelir. Sunucunuzdaki toplam RAM'in yaklaşık %60 ila %70'inimy.cnfdosyasındainnodb_buffer_pool_sizeparametresine ayırın. Böylece veritabanınız tüm aktif tabloları doğrudan ultra hızlı RAM'de tutarak diske hiç dokunmadan sorguları yanıtlar.- MyISAM'ı Kalıcı Olarak Yasaklayın: Yeni kurulan tabloların kazara MyISAM olmasını engellemek için
my.cnfiçinedefault_storage_engine = InnoDBsatırını ekleyin.
Döner kapıyla acil servis yönetilemeyeceği gibi, MyISAM ile de e-ticaret yönetilemez. Donanıma yüz binlerce lira yatırıp en temel mimari motor tercihini gözden kaçırmak, Ferrari'ye tahta tekerlek takıp yarışa çıkmaktan farksızdır. Performans donanımın büyüklüğünde değil; verinin damarlarda nasıl aktığını bilen doğru mimari kararlarda gizlidir.