Teknoloji

WooCommerce için MySQL/InnoDB Tuning Kontrol Listesi: Buffer Pool, İndeksleme ve Slow Query Analizi Nasıl Akıllıca Yapılır?

İçindekiler

Kasa Kuyruğu Uzadığında Hissettiğin O Gerginlik: WooCommerce ve MySQL’i Sakinleştirme Yolculuğu

Hiç başınıza geldi mi? Kampanya sayacı geri sayarken sitede bir şeyler ağırlaşır, ürün sayfaları geç gelir, ödeme adımında küçük takılmalar olur ve o çok tatlı dönüşüm grafiklerinin ucu aşağı kıvrılmaya başlar. Bir gün tam da böyle bir akşamüstü, ofiste kahvemi tazelerken loglara baktım ve her şeyin ortak bir adreste kesiştiğini fark ettim: MySQL. O gün anladım ki, WooCommerce’in kalp atışları aslında InnoDB’nin ritmine bağlı. Buffer Pool doğru nefes alamıyorsa, indeksler doğru yerde değilse ve slow query defteri kabarmışsa, en iyi sunucu bile mızıkçılık yapabiliyor.

Bu yazıda seni adım adım bir tuning turuna çıkaracağım. Buffer Pool’u nasıl ayarlayacağımızdan başlayacağız, WooCommerce tablolarında indeksleri nerede güçlendireceğimizi konuşacağız, sonra da slow query analizini gündelik alışkanlık haline getirecek küçük bir ritüele bağlayacağız. Arada kendi sahadan notlarımı, “mesela şöyle düşün” diye anlatacağım ufak anları ekleyeceğim. Hedef net: Siparişlerin arttığı, kampanyanın coştuğu o anlarda sitenin sakin ve hızlı kalması. Hadi başlayalım.

WooCommerce Trafiği Neden MySQL’de Düğümlenir?

Okuma-yazma dengesi: Sepetteki her tık bir izi bırakır

WooCommerce, ürün listelemeden sepete, kupondan ödemeye kadar sürekli hamle yapar. Bir kullanıcı ürün sayfasını açtığında okuma ağırlıklı işlemler, ödeme adımına geldiğinde ise yazma ağırlıklı işlemler devreye girer. Okuma hızlanır, yazma biraz daha titiz davranır. Çünkü yazma dediğin şey, siparişin geleceğini garantiye almak demek. InnoDB de bu dengeyi Buffer Pool, redo log ve flush davranışlarıyla korur. Kampanya anlarında birden çok kullanıcı aynı anda sepete dokunduğunda, bu minik yazma yoğunluğu hızla büyüyen bir trafiğe döner.

Mesela şöyle düşün: Bir markette kasaların önüne kurulan minik el arabaları gibi, Buffer Pool da verileri belleğe yerleştiriyor. Arabalar doğru yerdeyse sıra hızlı akıyor. Ama arabalar hem çok küçük hem de yanlış yerdeyse, ürünler tekrardan raftan taşınmak zorunda kalıyor. Diskten getir-götür başlıyor ve kuyruk uzuyor.

Ölçmeden ayar olmaz: Küçük bir temel fotoğraf çek

İşe girişmeden önce, sistemin “normal” halini öğrenmek iyi bir refleks. Basit bir dönem seç, örneğin geçen hafta aynı saat aralığı. CPU eğrileri, disk bekleme süreleri, MySQL bağlantı sayısı ve en önemlisi sayfa yanıt süreleri… Sonra bu fotoğrafın üstüne tuning sonrası başka bir fotoğraf koy. Aradaki fark, yaptığın ayarın işe yarayıp yaramadığını anlatır. Bu düşünme şekli, seni “rastgele ayar” yapmaktan korur.

Eğer altyapının enerjisini daha yukarı taşımak istiyorsan, sunucu tarafındaki bütünsel ayarları da hatırla. Bizim şu rehber, WordPress için sunucu tarafı optimizasyonunda neyi, ne zaman, nasıl ayarlamalısın, resmin tamamını görmek için güzel bir eşlikçi olur. Bir diğer tarafta, WooCommerce’in gerçekçi yüklerini tahmin etmek için kapsamlı kapasite planlama rehberine göz atmak, doğru miktarda kaynakla yola çıkmanı sağlar.

Buffer Pool: InnoDB’nin Nefesi Ne Kadar Uzun Olmalı?

Ne kadar RAM ayırmalı? “Yeterince büyük, ama aşırı değil” dengesi

Buffer Pool, InnoDB’nin en önemli belleği. Sık okunan sayfaları, indeksleri ve veri sayfalarını burada tutar. Mantık basit: Ne kadar çok veriyi RAM’de tutarsan, diske o kadar az uğrarsın. Ama her güzel şeyin bir dozu var. Tüm RAM’i MySQL’e vermek, sistemin nefesini keser. İşletim sistemi, PHP-FPM, Nginx/Apache, Redis veya arka plandaki diğer servisler de pay ister.

Pratik bir yaklaşım seviyorsan şöyle düşün: Sunucundaki toplam RAM’in önemli bir kısmını Buffer Pool’a ayır, ama operasyon sistemine ve uygulamalara makul bir alan bırak. Msela 32 GB RAM’li bir sunucuda, WooCommerce ağırlıklı bir trafik için Buffer Pool’u geniş tutmak akıllıca olur; fakat PHP süreçlerinin ve dosya sistemi önbelleğinin darlanmamasına da dikkat et. Hedef, diskten okumayı azaltırken, sistemin genel istikrarını bozmamak.

Buffer Pool ayarlarını yaparken, MySQL’in InnoDB Buffer Pool dokümantasyonuna göz atmak akıl açar. Orada meselelerin özünü sade bir dille anlatırlar. Sen yine de formül ezberlemek yerine, kendi sitenin erişim desenine güven. Ürün sayfaları çok büyük görseller ve uzun açıklamalarla doluysa, veritabanının tuttuğu alanlar da artar. Tersine, daha yalın bir katalogda bellek yükü daha az olur.

Buffer Pool parçaları, arka plan temizlikçisi ve flush düzeni

Buffer Pool büyüdükçe, içindeki sayfaları düzenli temizlemek ve yazmak da önemli hale gelir. Burada iki ayar özellikle hoşumuza gider: çok çekirdekli makinelerde innodb_buffer_pool_instances ile havuzu mantıklı parçalara bölmek ve innodb_page_cleaners ile arka plan yazıcılarını artırmak. Çok büyük bir havuzu tek parça bırakmak yerine, makinenin çekirdek sayısına uyumlu birkaç parça halinde kullanmak, kilitlenmeleri azaltır.

Flush davranışları ise bir denge oyunu gibidir. Çok agresif yazarsan disk yorulur, çok tembel davranırsan yazma patlamalarında tıkanma yaşarsın. innodb_flush_neighbors ve innodb_io_capacity ayarları ile diskin hızına uygun bir tempo bul. NVMe gibi hızlı disklerde kapasite değerlerini biraz yukarı taşımak mümkünken, daha mütevazı donanımlarda ortayı bulmak daha doğrudur. Amaç, sipariş akarken Buffer Pool’un sırtını rahatlatmak.

Redo log: O son hamleyi güvenli saklama sanatı

Yazma işlemlerinde işin sigortası redo log. Doğru boyutta değilse, sık sık geri dönüp temizlik yapmak zorunda kalır ve sistem gereksiz yere dalgalanır. Boyutu çok küçük olursa, beklenmedik yoğunluklarda nefesi kesilir. Çok büyük olursa toparlamak zorlaşır. Bu, kampanya anlarındaki yazma yoğunluğu ile ilişkili bir karar. innodb_log_file_size ve innodb_log_files_in_group ikilisiyle rahat bir alan açmak, Buffer Pool’un sırtından yük alır.

Bir de şu meşhur innodb_flush_log_at_trx_commit var. Bu ayar, yazma hızını ve veri güvenliğini aynı terazide tartar. Tam güvenlik istiyorsan en sıkı ayarla devam edersin, küçük esneklik kabul ediyorsan ara ayarlarla yazma hızını rahatlatırsın. Üretimde karar verirken, siparişlerin kritikliği ve altyapının UPS, RAID ve yedekleme disiplini gibi dayanaklarını da düşün. Veriyi asla riske atma; performans kazanırken güvenlikten vazgeçmemek temel bir prensip.

Geçici tablolara küçük bir bakış: tmp_table_size ve dostları

WooCommerce sorgularında bazen geçici tablolara ihtiyaç duyulur. Birleştirmeler, sıralamalar, raporlar… tmp_table_size ve max_heap_table_size değerlerini tutarlı bir seviyeye getirmek, bu geçici tablolardan disk yerine RAM’de faydalanmanı sağlar. Fakat bu değerleri abartmak, beklenmedik bellek tüketimlerine yol açabilir. Kural aynı: Yeterli ama aşırı değil. Ayrıca sort_buffer_size veya join_buffer_size gibi oturum tabanlı alanların çok büyütülmesinin, bağlantı sayısı arttığında toplam RAM’i zorlayabileceğini aklında tut.

İndeksleme: WooCommerce Tablolarında Gizli Kısayolları Açmak

wp_postmeta kara deliği: meta_key ve meta_value’nun terbiye edilmesi

WooCommerce’in en çok konuşulan masallarından biri wp_postmeta. Ürünlerin, varyasyonların, fiyatların, özel alanların çoğu burada konuşur. Sık yaşanan dert şudur: meta_value üzerinde arama yapman gerekir, ama o alan metinsel ve geniştir. Bu durumda tam metin arama gibi farklı stratejiler gündeme gelebilir, fakat pratikte çoğu sorgu meta_key + post_id çizgisinde toparlanır. Mesela stok takibi, fiyat karşılaştırması, görünürlük filtreleri gibi işler. Burada işine yarayacak şey, doğru sütun sıralamasına sahip bir bileşik indeks. Sorguların en sık nereden daraldığına göre (post_id, meta_key) veya (meta_key, post_id) düzeni, filtrelemeyi hızlandırır.

Benim sahada sık gördüğüm durum şu: Geliştirici tarafında küçük bir rapor yazılıyor, bir iki ek koşul ekleniyor derken “hızlı çalışıyor gibi” hissi oluşuyor. Trafik gerçek hayata karıştığında ise sorgu planı farklı bir yola sapıyor. Çözüm basit: Sorgunun gerçek yüzünü EXPLAIN ile gör ve ona göre indeksle. Bu ufak alışkanlık, postmeta’yı bir karanlık kuyu olmaktan çıkarır.

Sipariş cephesi: wc_order_stats ve wc_order_product_lookup ile barış

WooCommerce’ın modern tabloları olan wc_order_stats ve wc_order_product_lookup, sipariş özetlerini ve kalem detaylarını daha okunaklı bir yapıya taşır. Sipariş listesinde tarih aralığı, durum, müşteri ID’si gibi filtreler yaygındır. Bu yüzden date_created, status ve customer_id üzerine uygun bileşik indeksler, en yoğun anlarda fark yaratır. Ürün bazlı raporlar, kategori bazlı kırılımlar ve kampanya analizleri için de lookup tablosu üzerinde ürün ID’si odaklı indeksler doğru adrestir. Buradaki işin püf noktası, en sık kullanılan filtreleri öncelemek ve gereksiz her ek indeksten kaçınmaktır. Çünkü her indeks yazma maliyeti demek; sipariş kaydederken fazladan yük taşımak istemezsin.

Tek bir örnek üzerinden düşünelim. Yönetim panelinde geçmiş 7 günün iptal edilmiş siparişlerini durum ve tarih ile listeliyorsun. Sorgu planında tarih aralığına göre tarama yapılıyor ve üstüne status filtresi geliyor. Bu durumda (status, date_created) ya da (date_created, status) arasında seçim, sorgunun nereden daraldığına bağlı. EXPLAIN burada pusulan. Bir bakışta, indeksin hangi kolu kullandığını anlatır.

Ürünler, varyasyonlar ve kategori ilişkileri

Varyasyonlu ürünlerin çok olduğu kataloglarda, wp_posts, wp_term_relationships ve wp_postmeta üçlüsü birlikte dans eder. Kategori üzerinden ürün listeleme yaparken, ilişki tablosundaki term_taxonomy_id ve object_id odaklı indeksler yol açar. Varyasyon ararken, ebeveyn ürün ile bağlantıyı doğru kurmak ve post_type + post_status kısıtını boşa çıkarmamak, gereksiz taramaları azaltır. “Tek bir sayfa ağır” dediğinde, çoğu zaman arka tarafta birkaç küçük indeks dokunuşu ve sorgu düzenlemesi yeterli olur.

İşin hoş yanı şu: İndeksler görünmez kahramanlar gibidir. Doğru yerde olduklarında kimse onları fark etmez, her şey hızlıdır. Yanlış yerde veya gereğinden fazla olduklarında ise yazma tarafında usul usul bir yük bindirirler. Dengeyi, gerçek trafik ve EXPLAIN çıktılarıyla kurarsın.

Slow Query Analizi: Sorunu Bulmanın Sakin Yolu

Slow query log: “Nerede takılıyoruz?” sorusunun dürüst cevabı

İnan bana, slow query log dosyası iyi bir arkadaş gibi. Ne kadar net olursan, o kadar yardımcı olur. Başlangıç için slow_query_log’u aktif et, long_query_time değerini makul bir eşiğe indir ve bir süre gerçek trafik altında veri topla. “İndeks kullanılmayan sorguları da görmek istiyorum” dersen log_queries_not_using_indexes ile çemberi genişletirsin ama çok gürültü üretebileceğini unutma. Sonra bu dosyayı bir analiz aracından geçir ve kalıpları yakala.

Küçük bir ipucu: Üretimde eşiği aşırı düşük tutmak gereksiz kalabalık çıkarır. Önce sorunlu saatleri hedefle, oradan daralt. Birkaç gün sonra tekrar bak, iyileşme grafiğini böyle çizersin.

EXPLAIN ile sorgunun iç sesi

EXPLAIN çıktısını okumak, sorgu planını doğrudan görmek demek. Hangi indeks kullanılmış, tahmini kaç satır taranmış, sıralama nerede yapılmış… Çok teknik detaya boğmadan, şu alışkanlık yeterli: Filtrelediğin sütunların indeksli olduğundan emin ol, sıralama yaptığın sütunlar indeksle uyumlu çalışsın ve mümkünse gereksiz geniş tablolardan önce daraltıcı tablolara yönel. MySQL EXPLAIN çıktısının anlatımı kısa bir okumayla bile iyi bir fark yaratır.

Mesela kampanya raporu yazarken, önce tarih aralığını daralt, sonra durumu filtrele, en son kategori ya da müşteri bilgisiyle tatlandır. Bu basit yol, hem EXPLAIN’ı güzelleştirir hem de sunucunun nefesini açar.

pt-query-digest ile kalabalığı özetlemek

Bir dönem geçtikten sonra elinde büyük bir slow log olur. Onu tek tek okumak yerine, pt-query-digest ile gruplamak harika bir kolaylık sağlar. Ben genelde sorguları normalleştirir, en çok zaman alan ilk birkaç gruba odaklanırım. Buradan çıkan dersler, indeks düzeltmeleri veya sorgu iyileştirmeleri için doğrudan aksiyona dönüşür. Aracı merak ediyorsan, pt-query-digest hakkında özet bilgi işini görür.

Bu ritmi haftalık bir alışkanlığa çevirdiğinde, performans sorunları büyümeden küçülür. Logları dinleyen bir kulak geliştirirsin, işte bu kulak günün birinde kampanya akşamını kurtarır.

Performance Schema ve sys schema ile hızlı bir bakış

Detaya inmek istediğin anlarda Performance Schema ve onun üstünde çalışan sys schema güzel kestirme yollar sunar. En çok CPU harcayan sorgu tipleri, kilit beklemeleri, dosya I/O özetleri… Buradan aldığın sinyaller EXPLAIN ve indeks ayarlarına doğrudan yön verir. Kulağa ağır gelebilir ama meraklandığında küçük adımlarla başla, bir iki görünüm oku, sonra yavaş yavaş derinleş.

Gerçek Hayattan Minik Bir Kontrol Listesi Akışı

Bir projede başı sıkışmış bir mağazayı sakinleştirirken şu sırayı takip ettik ve iyi sonuç aldıydık. Önce yedekleri tazeledik, çünkü tuning her zaman güvenli bir omuz ister. Sonra Buffer Pool’u makinenin kapasitesine uygun şekilde büyüttük ve havuzu birkaç parçaya böldük. Redo log boyutunu güncel trafiğe uygun hale getirdik. Bu aşamada sunucu izleme araçlarında disk bekleme sürelerinin düştüğünü görmek motive edici oldu.

Ardından slow query log’u birkaç gün açık tuttuk. pt-query-digest ile en çok zaman harcayan üç sorguyu bulduk. Hepsi de farklı şekillerde postmeta ve sipariş özet tablolarıyla ilgiliydi. EXPLAIN’ı açınca, bazı sorguların indeksleri kullanılmadığını fark ettik. Küçük iki bileşik indeks ekledik ve sorguların sıradaki davranışı tamamen değişti. Sonraki günlerde aynı saatlerde yaptığımız yük testlerinde, sayfa yanıtlarının belirgin ölçüde iyileştiğini gözlemledik.

Özetle, kontrol listesi dediğin şey bir roman olmak zorunda değil. Birkaç güçlü sahne, geri kalan her şeyi toparlar: yedek al, Buffer Pool’u doğru boyutlandır, slow log topla, EXPLAIN ile yüzleş, indeksleri akıllıca düzenle ve tekrar ölç. İşte bu döngü, projeni güvenle büyütür.

Bu arada, eğer arka tarafta önbelleği de doğru kurmak istersen, WooCommerce için kalıcı nesne önbelleği ve TTL ayarlarına dair şu pratik rehber çok işlev görüyor. Uygulama katmanındaki doğru önbellek, veritabanının yükünü hafifletip tuning hamlelerini daha etkili kılar.

Sunucu Tarafı Dokunuşları: Küçük Ayarlar, Büyük Sükûnet

İş sadece MySQL ayarlarıyla bitmiyor. Disk katmanında hızlı ve istikrarlı bir depolama kullanmak, bu işe yapılan en büyük iyilik. Dosya sistemi önbelleği için işletim sistemine makul RAM bırakmak, ani dalgalanmaları yumuşatır. Swap’in varlığı bir emniyet yastığıdır ama yoğun kullanımı performansı bozar. Bazı çekirdek ayarlarıyla, örneğin bellek kırpışmalarını azaltmak ve şişkin sayfa davranışlarını kapatmak gibi ufak dokunuşlar, özellikle yoğun anlarda sistemi daha dengeli tutar.

Bir diğer kritik konu, düzenli ve sağlıklı yedekleme. MySQL’i rahatlatırken veriyi asla riske atma. “Bir şey güncellemeden önce ben yedeği görmek istiyorum” alışkanlığı, uyku kalitesini bile artırır. Bu konuda kafanın bir köşesinde dursun diye, MySQL/MariaDB yedekleme stratejilerini derli toplu anlattığımız bir yazıyı bırakıyorum. Sen yine de tuning hamlelerinden önce, otomatik yedeklerin gerçekten çalıştığını test etmeden ilerleme.

Kaynak seçimi aşamasındaysan ve altyapıyı büyütmeyi düşünüyorsan, doğru VPS kaynaklarını seçme rehberi de güzel bir eşlikçi olur. CPU, RAM ve disk I/O dengesini baştan iyi kurmak, veritabanı tuning’ini kat kat etkili hale getirir.

WooCommerce İçin İnce Ayar: Adım Adım Yol ve Küçük Sırlar

Önce ölç, sonra ayarla

Buffer Pool büyütmek her zaman sihirli değnek gibi hissedilir, ama nerede duracağını bilmek de bir sanattır. Ölçmeye, grafiklere bakmaya, EXPLAIN çıktısını okumaya alış. Birkaç gün aynı tempoda koştur ve farkı hisset. Dramatik adımlar atmak yerine küçük ve kontrollü değişiklikler, sistemin doğasını korur.

İndeks eklerken, yazma maliyetini unutma

İndeksler okuma yaptığında kurtarıcıdır, yazma yaptığında fazladan çaba ister. Sipariş kaydı, stok güncellemesi, kupon kullanımı gibi yazma içeren anlar arttıkça, her indeksin güncellenmesi gerekir. Bu yüzden gerçekten iş gören indeksleri tut, gereksiz olanları temizle. Bileşik indekslerde sütun sırası, sorgunun en çok daraldığı yere göre belirlenmeli. Birkaç EXPLAIN denemesi, seni doğru sıraya götürür.

Slow query analizi bir kez değil, rutin

Slow log’u açıp bir defa bakmakla iş bitmiyor. Trafiğin şekli değişir, kampanyalar yeni sorguları ortaya çıkarır, eklentiler farklı davranışlar üretir. Haftalık veya iki haftalık bir ritimle slow query analizi yapmak, performansı sürekli canlı tutmanın en pratik yolu. Üç beş küçük iyileştirme, bazen bir donanım yükseltmesinden daha çok sonuç getirir.

Kodu da unutma

Bazen sorun veritabanında değil, sorguyu inşa eden kod satırlarında saklıdır. Gereksiz join, aceleye gelmiş bir LIKE koşulu, sayfalandırmanın yanlış uygulanması… Kod tarafında küçük düzenlemelerle veritabanı mucize işler. Bu noktada uygulama katmanındaki önbellek kuralları, içerik dağıtımı ve HTML cache gibi başlıklar da devreye girer. Eğer bu tarafla daha detaylı ilgilenmek istersen, WordPress ve WooCommerce’de CDN önbellek kuralları yazısı hızın dış çeperini toparlamana yardım eder.

Kapanış: Tuning Bir Maraton, Sprint Değil

Bugün anlatmaya çalıştığım şey, WooCommerce’in veritabanı tarafında huzur bulmanın sırları. Buffer Pool ile belleği doğru kullan, indekslerle sık kullanılan yolları kısalt ve slow query analizi ile sorunu büyümeden yakala. Hepsi kendi aralarında anlaşınca, site akşam trafiğini bir pazar gezmesi gibi sakince atlatır. Tuning tek seferlik bir iş değil; ritim tutturduğunda gerçek meyveyi toplarsın.

Pratik birkaç notla kapatayım. Büyük değişikliklerden önce yedek al; minik ayarlarla ilerle, her adımda tekrar ölç; ekipteki herkesin görebileceği basit bir dashboard hazırla; kampanya öncesi küçük bir stres testi yap. Eğer bugün birkaç ayarı dener ve bir iki sorguyu iyileştirirsen, muhtemelen yarın kasada daha az bekleme göreceksin. Umarım bu yazı sana ilham olmuştur. Sorularını, yaşadığın ilginç vakaları ve aklına takılan ufak ayrıntıları paylaşmak istersen ne güzel. Bir sonraki yazıda görüşürüz; bu arada kahveni tazelemeyi unutma.

Kaynakça ve Faydalı Okumalar

Teknik ayrıntıları sade tutmaya çalıştım, ama derinleşmek istersen buralar güzel başlangıç noktaları: InnoDB Buffer Pool’un resmi anlatımı, EXPLAIN çıktısına pratik bir bakış ve pt-query-digest ile slow log özetleme. İçerideki büyük resmi görmek için ise şu üç rehber iyi arkadaşlık eder: WordPress için sunucu tarafı optimizasyon, WooCommerce kapasite planlama rehberi ve MySQL/MariaDB yedekleme stratejileri.

Sıkça Sorulan Sorular

Uygulama ve işletim sistemi için makul alan bırakarak RAM’in büyük bir kısmını Buffer Pool’a ayır. Çok büyük yapmak yerine adım adım artır, her değişiklikten sonra metrikleri ölç.

Genelde wp_postmeta, wc_order_stats ve wc_order_product_lookup öne çıkar. Sık filtrelenen sütunlar için bileşik indeksler eklemek, özellikle tarih ve durum temelli sorguları rahatlatır.

Önce makul bir eşik belirleyip birkaç gün veri topla. Ardından pt-query-digest ile sorguları gruplandır, en çok zaman alan ilk birkaç gruba odaklan ve EXPLAIN ile doğru indeksleri doğrula.