MySQL Error 2002, PHP uygulaması veritabanına bağlanamazken komut satırından yapılan MySQL bağlantısının çalıştığı durumlarda sık görülür. Tipik hata metni “No such file or directory” ya da “Connection refused” içerir. Bu senaryoda sorun çoğu zaman veritabanının tamamen kapalı olması değil; PHP’nin localhost için kullanmaya çalıştığı Unix socket dosyasının MySQL/MariaDB’nin gerçek socket yolu ile uyuşmamasıdır. PHP-FPM, chroot/container sınırı veya farklı yapılandırma dosyaları da aynı belirtiyi doğurabilir. Bu rehber, Linux üzerinde uygulama katmanındaki socket-TCP ayrımını güvenli biçimde teşhis edip düzeltmeye odaklanır.
Belirti ve kapsam: Hata yalnızca web uygulamasında mı oluşuyor?
Aşağıdaki örneklerden biri görülüyorsa bu rehberdeki senaryo geçerlidir:
SQLSTATE[HY000] [2002] No such file or directory
mysqli::real_connect(): (HY000/2002): No such file or directory
Can't connect to local MySQL server through socket '/yol/mysql.sock' (2)
Özellikle SSH üzerinden aşağıdaki test başarılıyken web sitesi, API veya kuyruk işçisi hata veriyorsa uygulamanın kullandığı PHP çalışma ortamı ile MySQL istemci ayarları farklıdır:
mysql -u uygulama_kullanici -p -h localhost veritabani_adi
Buradaki kritik ayrım şudur: Linux MySQL istemcilerinde localhost çoğunlukla TCP yerine Unix socket bağlantısı anlamına gelir. Buna karşılık 127.0.0.1 TCP/IP üzerinden bağlanmayı zorlar. Bu iki yol aynı kullanıcı yetkilerine, aynı socket dosyasına veya aynı erişim kuralına sahip olmak zorunda değildir.
MySQL Error 2002 için hızlı teşhis kontrol listesi
- MySQL ya da MariaDB servisi çalışıyor mu?
- Sunucuda gerçekten hangi Unix socket dosyası mevcut?
- Uygulamanın hata mesajındaki socket yolu, mevcut socket ile aynı mı?
- PHP CLI ile PHP-FPM aynı
php.inive aynı MySQL socket ayarını mı kullanıyor? - Uygulama container, chroot veya ayrı bir PHP-FPM havuzunda mı çalışıyor?
127.0.0.1ile deneme yapılırsa MySQL TCP’de dinliyor ve kullanıcı yetkisi uygun mu?
Olası nedenler ve ayırt etme yöntemleri
| Belirti | Olası neden | Güvenli yön |
|---|---|---|
| CLI çalışır, PHP hata verir | PHP-FPM ve CLI farklı socket/ini kullanıyordur | FPM yapılandırmasını gerçek socket ile eşleştirin |
| Hata “No such file or directory” | İstenen socket yolu yoktur veya çalışma alanında görünmüyordur | Socket yolunu ve izolasyon katmanını doğrulayın |
| 127.0.0.1 ile “Connection refused” | MySQL TCP’de dinlemiyordur ya da yanlış port kullanılmaktadır | Dinleme adresini ve portu kontrol edin |
| 127.0.0.1 ile “Access denied” | TCP bağlantısı ulaşır, fakat kullanıcı/host yetkisi uymaz | Kullanıcı tanımını ve yetkileri gözden geçirin |
| Sadece container içindeki uygulama hata verir | Host üzerindeki socket container içinde yoktur | Uygun ağ bağlantısı veya kontrollü socket paylaşımı planlayın |
Loglar ve temel teşhis komutları
1. Veritabanı servisinin durumunu kontrol edin
Dağıtıma ve kurulu pakete göre servis adı mysql veya mariadb olabilir. Yalnızca sisteminizde bulunan adı kullanın.
sudo systemctl status mysql
sudo systemctl status mariadb
sudo journalctl -u mysql -n 100 --no-pager
sudo journalctl -u mariadb -n 100 --no-pager
Servis durmuşsa loglardaki disk alanı, izin, InnoDB veya yapılandırma hatasını incelemeden körlemesine tekrar başlatmayın. Üretim veritabanında yeniden başlatma aktif işlemleri kesebilir; planlı bakım penceresi ve güncel yedek tercih edilmelidir.
2. Mevcut socket dosyasını ve TCP dinlemeyi bulun
sudo ss -xl | grep -Ei 'mysql|mariadb'
sudo find /run /var/run -type s -name '*mysql*.sock' 2>/dev/null
sudo ss -lntp | grep -E ':(3306)\b'
Modern Linux dağıtımlarında /var/run genellikle /run için sembolik bağlantıdır. Buna rağmen uygulamanın açıkça beklediği yol ile bulunan yolun birebir aynı olduğundan emin olun. Birden fazla MySQL/MariaDB örneği bulunan sistemlerde yalnızca dosya adına göre karar vermeyin.
3. İstemci ve sunucu tarafındaki tanımları inceleyin
my_print_defaults client mysql mysqld mariadbd
mysql --help | grep -A1 -i 'Default options'
my_print_defaults, etkin seçenek dosyalarından okunan parametreleri gösterir. Dağıtıma göre ana dosyalar /etc/my.cnf, /etc/mysql/my.cnf veya bunların ek yapılandırma dizinleri olabilir. Dosya yolunu tahmin ederek değiştirmek yerine bu komutun çıktısı ve servis başlatma parametreleri üzerinden ilerleyin.
4. PHP-FPM günlüklerini kontrol edin
PHP sürümüne göre birim adı değişir. Debian/Ubuntu sistemlerinde örnek olarak php8.2-fpm, RHEL türevlerinde ise çoğunlukla php-fpm kullanılır.
sudo systemctl status php8.2-fpm
sudo journalctl -u php8.2-fpm -n 100 --no-pager
sudo systemctl status php-fpm
sudo journalctl -u php-fpm -n 100 --no-pager
Uygulamanın kendi hata günlüğündeki Error 2002 mesajını da kontrol edin. Hata metninde yazan socket yolu, çözüm için en değerli kanıttır.
Güvenli adım adım çözüm
Adım 1: Uygulama bağlantı hedefini netleştirin
Önce uygulamanın bağlantı ayarındaki host değerini bulun. Laravel gibi çerçevelerde bu değer genellikle ortam değişkeninde, özel PHP uygulamalarında ise bağlantı yapılandırmasındadır. Parola içeren yapılandırma dosyalarını terminal çıktısına, destek talebine veya sürüm kontrol sistemine kopyalamayın.
Host değeri localhost ise PHP, Unix socket kullanmayı deneyebilir. Hata mesajındaki socket yolu bulunmuş gerçek socketten farklıysa iki güvenli yaklaşım vardır:
- Uygulamanın MySQL socket ayarını gerçek socket yoluna eşlemek.
- TCP bağlantısına bilinçli olarak geçmek için host değerini
127.0.0.1yapmak.
İlk yaklaşım, aynı makinedeki yerel bağlantı için çoğu durumda daha doğrudandır. İkinci yaklaşım ise container veya chroot gibi socket görünürlüğünün sorun olduğu mimarilerde daha uygun olabilir.
Adım 2: Socket kullanılacaksa PHP ayarını gerçek yol ile eşleştirin
PHP’nin MySQL uzantıları için socket değerleri mysqli.default_socket ve pdo_mysql.default_socket seçenekleriyle tanımlanabilir. Bu değerlerin hangi dosyadan geldiğini önce doğrulayın. CLI ile FPM aynı yapılandırmayı kullanmayabileceği için yalnızca php --ini çıktısına dayanmayın.
php --ini
php -i | grep -Ei 'mysqli.default_socket|pdo_mysql.default_socket'
PHP-FPM tarafında ilgili sürümün ek .ini dosyasını veya havuz yapılandırmasını, sunucunuzdaki gerçek socket yoluna göre düzenleyin. Ardından yapılandırma sözdizimini doğrulayıp yalnızca PHP-FPM hizmetini yeniden yükleyin ya da yeniden başlatın. Komutun servis adı sürüme bağlıdır:
sudo systemctl reload php8.2-fpm
# Reload desteklenmiyorsa:
sudo systemctl restart php8.2-fpm
PHP-FPM yeniden başlatması o havuzdaki devam eden istekleri etkileyebilir. Yoğun sistemlerde bakım penceresi kullanın. Socket dosyasını elle oluşturmak, rastgele chmod 777 uygulamak veya /run altına kalıcı dosya yerleştirmek doğru çözüm değildir; /run çoğu sistemde yeniden başlatmada temizlenir.
Adım 3: TCP kullanılacaksa 127.0.0.1 ve yetkileri doğrulayın
Uygulama host değerini 127.0.0.1 yaptığınızda MySQL’in yerel TCP bağlantısını kabul etmesi gerekir. Önce uygulama sunucusunda, aynı kullanıcı bilgileriyle kontrollü test yapın:
mysql -u uygulama_kullanici -p -h 127.0.0.1 -P 3306 veritabani_adi
Bu komut “Connection refused” verirse MySQL TCP’de dinlemiyor olabilir. MySQL yapılandırmasındaki bind-address, skip-networking ve port ayarlarını inceleyin. Sadece yerel uygulama bağlantısı gerekiyorsa MySQL’i genel ağa açmak için 0.0.0.0 adresine bağlamayın; 127.0.0.1 ile sınırlı dinleme daha güvenli bir tasarımdır.
Test “Access denied” veriyorsa ağ bağlantısı çalışıyordur; sorun kimlik doğrulama veya kullanıcı host eşleşmesidir. MySQL’de 'kullanici'@'localhost' ile 'kullanici'@'127.0.0.1' farklı eşleşmeler olabilir. Mevcut kullanıcı tanımlarını yetkili bir oturumdan inceleyin:
mysql -u root -p -e "SELECT User, Host FROM mysql.user WHERE User = 'uygulama_kullanici';"
Yetki değişikliği yapmadan önce uygulamanın gerçekten hangi bağlantı yöntemini kullanacağını doğrulayın. Gereksiz geniş host tanımları veya tüm ağlara açık yetkiler vermeyin.
Adım 4: Container veya chroot ayrımını giderin
Uygulama Docker, LXC, chroot ya da benzeri bir izolasyon içinde çalışıyorsa host makinedeki /run/mysqld dizini uygulamanın dosya sisteminde mevcut olmayabilir. Bu durumda host socket yolunu PHP ayarına yazmak tek başına işe yaramaz. Uygulama ile veritabanı arasında kontrollü bir ağ bağlantısı kullanmak veya mimariye uygun, izinleri daraltılmış bir socket paylaşımı tasarlamak gerekir. Container içine host MySQL socketini gelişigüzel bağlamak yerine ağ segmentasyonu, kimlik bilgileri ve erişim sınırlarını değerlendirin.
Çözümü doğrulama
Değişiklikten sonra hem seçtiğiniz bağlantı yolunu hem de uygulamayı ayrı ayrı test edin. Socket kullanıyorsanız:
mysql -u uygulama_kullanici -p --protocol=socket --socket=/gercek/socket/yolu.sock veritabani_adi
TCP kullanıyorsanız:
mysql -u uygulama_kullanici -p --protocol=TCP -h 127.0.0.1 -P 3306 veritabani_adi
Ardından uygulamanın hata üreten sayfasını veya sağlık denetimi uç noktasını yeniden deneyin. PHP-FPM ve uygulama günlüklerinde yeni Error 2002 kaydı oluşmadığını kontrol edin. Önbellek kullanan çerçevelerde yapılandırma önbelleğinin güncellenmesi gerekebilir; bunun komutu çerçeveye göre değiştiğinden uygulamanızın resmi çalışma prosedürünü izleyin.
Önleme: Socket uyumsuzluğunun tekrarını engelleme
- MySQL socket yolunu, PHP-FPM socket ayarını ve uygulama bağlantı hedefini envanter dokümanında birlikte kaydedin.
- PHP sürümü yükseltildiğinde yeni FPM servisinin ayrı
.iniyükleyebileceğini değişiklik kontrolüne ekleyin. - Uygulama ve MySQL farklı container ya da sunuculardaysa baştan TCP, TLS ve en az ayrıcalık ilkesiyle tasarım yapın.
- Servis yeniden başlatma sonrası uygulama bağlantısını da kapsayan bir sağlık kontrolü uygulayın.
- Geçici hata bastırma, socket dosyası kopyalama veya herkese açık dosya izinleri yerine kök nedeni düzeltin.
Sonuç: MySQL Error 2002 çoğu zaman bağlantı yolu uyuşmazlığıdır
MySQL Error 2002 PHP tarafında görülürken MySQL servisinin çalışıyor olması yanıltıcı olabilir. Hata mesajındaki socket yolunu, sunucudaki gerçek socketi, PHP-FPM’in etkin yapılandırmasını ve gerekirse 127.0.0.1 TCP testini birlikte değerlendirmek doğru teşhisi sağlar. Socket veya TCP yöntemlerinden birini bilinçli seçip kullanıcı yetkilerini o bağlantı yoluna göre dar kapsamda düzenlemek, sorunu kalıcı ve güvenli biçimde giderir.
Sık sorulan sorular
localhost yerine 127.0.0.1 yazmak her zaman çözüm olur mu?
Hayır. Bu değişiklik socket yerine TCP kullanır. MySQL TCP’de dinlemiyorsa “Connection refused”, kullanıcı TCP için yetkili değilse “Access denied” alınabilir.
MySQL çalışıyorsa neden PHP’de Error 2002 alıyorum?
PHP-FPM farklı bir socket yolu, farklı bir yapılandırma dosyası veya host sistemden izole edilmiş bir dosya sistemi kullanıyor olabilir. CLI testinin çalışması FPM ayarlarının doğru olduğunu kanıtlamaz.
Socket dosyasına chmod 777 vermeli miyim?
Hayır. Bu işlem gereksiz erişim riski doğurur ve yeniden başlatma sonrası kaybolabilir. Socket sahibi, grup izinleri ve uygulamanın çalışma kullanıcısı mimariye uygun biçimde değerlendirilmelidir.
MySQL portunu internete açmak gerekli mi?
Hayır. Uygulama ve MySQL aynı sunucudaysa TCP için yalnızca 127.0.0.1 üzerinde dinlemek yeterli olabilir. Uzak bağlantı zorunluysa ağ erişimini ve kullanıcı yetkilerini mümkün olan en dar kapsamda sınırlayın.
Bu hata veritabanı bozulduğu anlamına gelir mi?
Genellikle hayır. Error 2002 bir bağlantı hatasıdır. Ancak servis günlüklerinde InnoDB başlatma hatası veya depolama hatası varsa veri bütünlüğü için ayrı bir inceleme ve yedekleme planı gerekir.