Merhaba arkadaşlar, bugün sizlere özellikle MySQL 5.7 ve üzeri sürümlerde kritik öneme sahip bir optimizasyon ve güvenlik adımından bahsedeceğim: Sorgu Önbelleğini (Query Cache) devre dışı bırakma. Bu özellik, eskiden performans için kullanılsa da artık ciddi performans darboğazlarına ve hatta sistem kilitlenmelerine yol açabiliyor. Bu rehberde, neden kapatmanız gerektiğini, nasıl kapatacağınızı ve bu özellik olmadan nasıl daha etkili bir performans elde edeceğinizi adım adım anlatacağım.
Neden Query Cache Kapatılmalı?
MySQL geliştiricileri, 5.7.20 sürümünden itibaren bu özelliği "kullanımdan kaldırılmış (deprecated)" olarak işaretledi ve MySQL 8.0'da ise tamamen kaldırdı. Ana sebep, önbellek için global bir kilit (mutex) mekanizması olması. Yüksek eşzamanlılık (high concurrency) olan sistemlerde, bu kilit için yarışan çok sayıda sorgu, CPU kullanımını patlatıp sunucuyu adeta "kitliyor". Benim sunucularda yaşadığım en tipik belirti, anlık yük artışlarında CPU'nun %100'e çıkıp sorgu sürelerinin 10-20 katına çıkmasıydı. Eğer hala 5.7 kullanıyorsanız, bu ayarı kontrol etmeniz şart.
Mevcut Durumu Kontrol Etme
İlk olarak, Query Cache'in sunucunuzda aktif olup olmadığını kontrol edelim. MySQL'e root veya yetkili bir kullanıcı ile bağlanıp aşağıdaki komutu çalıştırın.
Eğer `query_cache_type` değeri `ON` veya `DEMAND` ise, önbellek aktif demektir. `query_cache_size` değeri ise önbellek için ayrılan belleği gösterir. Sıfırdan büyük bir değer (örneğin 1M) görüyorsanız, bu bellek alanı ayrılmış durumdadır.
Query Cache'i Devre Dışı Bırakma
Bu işlemi iki şekilde yapabilirsiniz: anlık olarak (sunucu yeniden başlayınca eski ayara döner) ve kalıcı olarak (konfigürasyon dosyasında).
1. Anlık Olarak Kapatma:
MySQL komut satırında aşağıdaki komutları çalıştırın. Bu, önbelleği hemen devre dışı bırakır ve belleği serbest bırakır.
2. Kalıcı Olarak Kapatma (ÖNERİLEN YÖNTEM):
Değişikliklerin sunucu yeniden başlatılsa bile kalıcı olması için MySQL konfigürasyon dosyasını düzenlemelisiniz. Dosya yolu genellikle /etc/mysql/my.cnf veya /etc/my.cnf şeklindedir. Dosyayı bir editörle açın (nano, vim).
`[mysqld]` bölümünün altına aşağıdaki satırları ekleyin. Eğer bu satırlar zaten varsa, değerlerini aşağıdaki gibi değiştirin.
Değişiklikleri kaydettikten sonra MySQL servisini yeniden başlatın. Benim sunucularda genelde kullandığım yöntem systemctl'dir.
Alternatif Performans Çözümleri
Query Cache kapandı, peki performansı nasıl artıracağız? Asıl odaklanmamız gereken yer burası. İşte uygulama seviyesinde ve veritabanı seviyesinde uygulayabileceğiniz çok daha etkili yöntemler:
1. Uygulama Seviyesi Önbellekleme (En Etkilisi):
Bu, Query Cache'ten katbekat daha iyidir. Sık değişmeyen verileri (örneğin site ayarları, kategoriler, sabit içerikler) Redis veya Memcached gibi bir bellek içi veri deposunda (in-memory store) saklayın. Bu sayede veritabanına hiç gitmezsiniz. Ben performans kritik projelerde kesinlikle Redis kullanıyorum.
2. Optimize Edilmiş İndeksler:
`EXPLAIN` anahtar kelimesi ile sorgularınızı analiz edin. Hangi sorgunun hangi indeksi kullandığını veya tam tablo taraması (full scan) yaptığını görün. Eksik indeksleri eklemek, performansı yüzlerce kat artırabilir.
3. Yavaş Sorgu Loglarını Analiz Etme:
MySQL'in yavaş sorgu loglarını aktif edin ve düzenli olarak inceleyin. long_query_time değerini 2 saniye gibi bir değere ayarlayarak başlayabilirsiniz.
4. MySQL Performans Şeması (Performance Schema):
5.7 ve üzeri sürümlerde gelen bu özellik, sunucunuzun iç işleyişini detaylıca izlemenizi sağlar. Hangi işlemin ne kadar kaynak tükettiğini görmek için mükemmel bir araçtır.
Sonuç ve Öneriler
Query Cache, artık tarihe karışmış ve modern yüksek trafikli sistemler için bir tehdit unsuru. Güvenli ve performanslı bir MySQL sunucusu için ilk yapmanız gereken işlemlerden biridir onu kapatmak. Asıl performans kazancını, yukarıda saydığım uygulama seviyesi önbellekleme ve sorgu optimizasyonu ile elde edeceksiniz.
Siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Redis veya Memcached kullanıyor musunuz? Yaşadığınız performans sorunları veya farklı yöntemleriniz varsa aşağıya yazmaktan çekinmeyin. Sorularınız için buradayım!
MySQL geliştiricileri, 5.7.20 sürümünden itibaren bu özelliği "kullanımdan kaldırılmış (deprecated)" olarak işaretledi ve MySQL 8.0'da ise tamamen kaldırdı. Ana sebep, önbellek için global bir kilit (mutex) mekanizması olması. Yüksek eşzamanlılık (high concurrency) olan sistemlerde, bu kilit için yarışan çok sayıda sorgu, CPU kullanımını patlatıp sunucuyu adeta "kitliyor". Benim sunucularda yaşadığım en tipik belirti, anlık yük artışlarında CPU'nun %100'e çıkıp sorgu sürelerinin 10-20 katına çıkmasıydı. Eğer hala 5.7 kullanıyorsanız, bu ayarı kontrol etmeniz şart.
İlk olarak, Query Cache'in sunucunuzda aktif olup olmadığını kontrol edelim. MySQL'e root veya yetkili bir kullanıcı ile bağlanıp aşağıdaki komutu çalıştırın.
SQL:
SHOW VARIABLES LIKE 'query_cache_type';
SHOW VARIABLES LIKE 'query_cache_size';
Eğer `query_cache_type` değeri `ON` veya `DEMAND` ise, önbellek aktif demektir. `query_cache_size` değeri ise önbellek için ayrılan belleği gösterir. Sıfırdan büyük bir değer (örneğin 1M) görüyorsanız, bu bellek alanı ayrılmış durumdadır.
Bu işlemi iki şekilde yapabilirsiniz: anlık olarak (sunucu yeniden başlayınca eski ayara döner) ve kalıcı olarak (konfigürasyon dosyasında).
1. Anlık Olarak Kapatma:
MySQL komut satırında aşağıdaki komutları çalıştırın. Bu, önbelleği hemen devre dışı bırakır ve belleği serbest bırakır.
SQL:
SET GLOBAL query_cache_type = OFF;
SET GLOBAL query_cache_size = 0;
2. Kalıcı Olarak Kapatma (ÖNERİLEN YÖNTEM):
Değişikliklerin sunucu yeniden başlatılsa bile kalıcı olması için MySQL konfigürasyon dosyasını düzenlemelisiniz. Dosya yolu genellikle /etc/mysql/my.cnf veya /etc/my.cnf şeklindedir. Dosyayı bir editörle açın (nano, vim).
Bash:
sudo nano /etc/mysql/my.cnf
`[mysqld]` bölümünün altına aşağıdaki satırları ekleyin. Eğer bu satırlar zaten varsa, değerlerini aşağıdaki gibi değiştirin.
INI:
[mysqld]
query_cache_type = 0
query_cache_size = 0
Değişiklikleri kaydettikten sonra MySQL servisini yeniden başlatın. Benim sunucularda genelde kullandığım yöntem systemctl'dir.
Bash:
sudo systemctl restart mysql
# veya eski sistemler için:
# sudo service mysql restart
Query Cache kapandı, peki performansı nasıl artıracağız? Asıl odaklanmamız gereken yer burası. İşte uygulama seviyesinde ve veritabanı seviyesinde uygulayabileceğiniz çok daha etkili yöntemler:
1. Uygulama Seviyesi Önbellekleme (En Etkilisi):
Bu, Query Cache'ten katbekat daha iyidir. Sık değişmeyen verileri (örneğin site ayarları, kategoriler, sabit içerikler) Redis veya Memcached gibi bir bellek içi veri deposunda (in-memory store) saklayın. Bu sayede veritabanına hiç gitmezsiniz. Ben performans kritik projelerde kesinlikle Redis kullanıyorum.
2. Optimize Edilmiş İndeksler:
`EXPLAIN` anahtar kelimesi ile sorgularınızı analiz edin. Hangi sorgunun hangi indeksi kullandığını veya tam tablo taraması (full scan) yaptığını görün. Eksik indeksleri eklemek, performansı yüzlerce kat artırabilir.
3. Yavaş Sorgu Loglarını Analiz Etme:
MySQL'in yavaş sorgu loglarını aktif edin ve düzenli olarak inceleyin. long_query_time değerini 2 saniye gibi bir değere ayarlayarak başlayabilirsiniz.
INI:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2
4. MySQL Performans Şeması (Performance Schema):
5.7 ve üzeri sürümlerde gelen bu özellik, sunucunuzun iç işleyişini detaylıca izlemenizi sağlar. Hangi işlemin ne kadar kaynak tükettiğini görmek için mükemmel bir araçtır.
Query Cache, artık tarihe karışmış ve modern yüksek trafikli sistemler için bir tehdit unsuru. Güvenli ve performanslı bir MySQL sunucusu için ilk yapmanız gereken işlemlerden biridir onu kapatmak. Asıl performans kazancını, yukarıda saydığım uygulama seviyesi önbellekleme ve sorgu optimizasyonu ile elde edeceksiniz.
Siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Redis veya Memcached kullanıyor musunuz? Yaşadığınız performans sorunları veya farklı yöntemleriniz varsa aşağıya yazmaktan çekinmeyin. Sorularınız için buradayım!