“MySQL server has gone away” mesajını görünce sunucunun tamamen kapandığını düşünmek kolay. Oysa bazen yalnız uygulamanın elinde tuttuğu eski bağlantı kapanmıştır. Bazen de büyük bir sorgu gönderilirken paket sınırı aşılmıştır. Aynı hata metnine tek bir ayar reçetesi uygulamayalım.
MySQL ve MariaDB'de istemcinin 2006 veya 2013 gibi bağlantı hataları görmesi, nedenin başlı başına kanıtı değildir. İsteğin hangi aşamasında koptuğunu kaydet: ilk bağlantıda mı, uzun bekleyişten sonraki ilk sorguda mı, yoksa büyük bir aktarımın hep aynı yerinde mi?
Önce kopmanın zamanını bul
Uygulama hata kaydı ile veritabanı kaydını aynı zaman aralığında karşılaştır. Sunucu yeniden başladıysa eski oturumların çalışmaya devam etmesini bekleyemeyiz. Linux'ta servis adı kurulumuna göre mysql, mysqld veya mariadb olabilir. Aşağıdaki örnek MariaDB içindir; saat aralığını kendi olayına göre değiştir:
sudo journalctl -u mariadb --since "30 minutes ago" --no-pager
sudo journalctl -k --since "30 minutes ago" --no-pager
İkinci komut çekirdek kayıtlarını gösterir; bellek yetersizliği nedeniyle süreç sonlandırılması gibi sistem olaylarını ararız. Her kurulum veritabanı hata kaydını journal'a yazmaz. Kayıt boşsa “sorun yok” demek yerine yapılandırılmış hata dosyasını veya hosting panelindeki veritabanı günlüklerini bul.
Veritabanına yeni bir yönetim oturumuyla bağlanabiliyorsan şu salt okunur sorgular başlangıç için yeterli:
SELECT VERSION(), @@version_comment;
SHOW GLOBAL STATUS LIKE 'Uptime';
SHOW GLOBAL VARIABLES LIKE 'log_error';
SHOW GLOBAL VARIABLES
WHERE Variable_name IN ('wait_timeout', 'interactive_timeout', 'max_allowed_packet');
SHOW SESSION VARIABLES
WHERE Variable_name IN ('wait_timeout', 'max_allowed_packet');
Uptime sunucunun çalışma süresini saniye cinsinden verir. Olay anına göre çok düşük olması yeniden başlama ihtimalini destekler; sebebini tek başına açıklamaz. GLOBAL genel ayarı, SESSION sorguyu çalıştırdığın bağlantının değerini gösterir. Yönetim bağlantısının değerini uygulamanın eski oturumuyla aynı kabul etme.
Uzun bekleyişten sonra ilk sorgu kopuyorsa
wait_timeout, boşta kalan bağlantının ne kadar bekleneceğiyle ilgilidir; sorgunun çalışabileceği toplam süreyi belirlemez. Bir işçi süreç bağlantıyı açıp uzun süre başka iş yapıyor, sonra aynı bağlantıya dönüyorsa sunucu onu kapatmış olabilir. Bağlantı havuzu da artık geçerli olmayan oturumu uygulamaya geri vermiş olabilir.
Önce uygulamanın bağlantı ömrünü ve havuzun doğrulama davranışını düzenle. Her bağlantıyı saatlerce açık tutmak yerine işin başında geçerli bir bağlantı edinmek daha uygun olabilir. MariaDB değişken belgesi, oturum değerinin bağlantı kurulurken nasıl belirlendiğini açıklıyor. Genel ayarı değiştirmek mevcut bütün oturumları aynı anda değiştirmek değildir.
Büyük bir INSERT veya aktarımda kopuyorsa
max_allowed_packet, tek iletişim paketinin sınırıyla ilgilidir. SQL dosyasının toplam boyutuyla aynı şey değildir. Yüzlerce küçük INSERT içeren dosya geçerken tek bir büyük INSERT veya BLOB alanı sınırı aşabilir. Sunucu ve istemci tarafındaki limitleri birlikte incele; yalnız phpMyAdmin yükleme sınırını büyütmek bu sorunu çözmeyebilir.
Aktarım hep aynı noktada duruyorsa ilgili sorgunun büyüklüğünü ve hata kaydını kontrol et. Ölçüm gerçekten paket sınırını gösteriyorsa gereken sınırı belirle veya veriyi uygun parçalara böl. Her sunucuya ezbere 1 GB sınırı vermek yerine iş yüküne göre karar ver. MySQL paket sınırı belgesi ve büyük SQL dosyası aktarma rehberi bu ayrımı tamamlıyor.
Kopan işlemi körlemesine tekrarlama
Bağlantı kesilince yazma işleminin kesinlikle yapılmadığı sonucuna varamayız. Sunucu işlemi tamamlayıp cevabı gönderememiş olabilir. Sipariş, ödeme veya stok hareketinde aynı sorguyu yeniden çalıştırmadan önce işlemin durumunu doğrula. Tekrara dayanıklı uygulama tasarımı ve işlem kimliği burada bağlantıyı yeniden açmaktan daha önemlidir.
Birden çok kullanıcı aynı anda etkileniyorsa sunucu yeniden başlaması, ağ yolu ve kaynak baskısı öne çıkar. Sorun yalnız tek işçi süreçteyse bağlantı yönetimine daha yakından bak. Bağlantı sayısı sınırına ulaşılması ise ayrı bir hata ailesi; onu 1040 bağlantı limiti yazısında ele alıyoruz.
Düzeltmeden sonra hatayı çıkaran bekleme veya aktarım senaryosunu yeniden dene. Yalnız yeni açılmış oturumda SELECT 1 çalışması, saatlerce yaşayan işçinin sorununun çözüldüğünü göstermez. Kopma saati, oturum davranışı ve MySQL'in olası nedenleri aynı bulguyu gösterdiğinde doğru ayarı değiştirmiş olursun.