dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/Hata Teşhis Kütüphanesi/mysql-1142-select-command-denied
MySQL
MySQL 5.7–8.4 LTSGüvenlik & Yetkilendirme
7 dk okuma
ERROR 1142 (42000): SELECT command denied to user for table / ERROR 1143 for column

MySQL Error 1142 — Yetki Verdim ama Neden Hâlâ Reddediliyor?

1142 hatasında USER() ile CURRENT_USER() farkı, host bazlı hesap eşleşmesi, veritabanı/tablo/kolon yetkileri ve MySQL 8 rollerinin etkinleştirilmesi.

İnceleyen:Principal Database Reliability Architect
Test Edilen Sürümler: MySQL 8.4 LTS, 8.0.40 & 5.7.44 (Debian / Docker 29.7)

Operasyonel Doğrulama & Güvenilirlik Standardı

Son Teknik İnceleme: 30 Ekim 2026
Test Edilen SürümlerMySQL 8.4 LTS & 8.0.40 (Docker 29.7) | Tarihsel: 5.7.44
Gerekli YetkiGRANT OPTION veya yetki yöneticisi (hesaba SELECT ve rol tanımlamak için)
Risk Seviyesi
MediumGereksiz FLUSH PRIVILEGES veya aşırı geniş 'app'@'%' yetkileri güvenlik yüzeyini büyütür
Beklenen ÇıktıUSER() ve CURRENT_USER() eşleşmesinin doğrulanması, rolün SET DEFAULT ROLE ALL ile etkinleştirilmesi ve 0 hata
Geri Dönüş (Rollback) Planı:REVOKE ile fazla yetkileri geri alıp dar host aralığıyla (10.0.2.%) rol bazlı yetkilendirme uygulama
MySQL 8.4 Docs: Privileges & Role Activation
İlk 60 Saniye Teşhis Protokolü:

Hata mesajı semptomdur, kök neden değildir. Sunucuyu yeniden başlatmadan veya rastgele ayar değiştirmeden önce aşağıdaki "Nedeni ayırt eden tek sorgu"yu çalıştırarak gerçek senaryoyu netleştirin.

▸Belirti

plaintext
ERROR 1142 (42000): SELECT command denied to user 'app'@'10.0.2.15' for table 'siparis' ERROR 1143 (42000): SELECT command denied to user 'app'@'10.0.2.15' for column 'tutar' in table 'siparis'

SQLSTATE kodu: 42000.

Bu hata, PostgreSQL'deki H-34 (permission denied for table) ve SQL Server'daki H-39 (Msg 229: SELECT permission was denied) rehberlerinin MySQL karşılığıdır; böylece veritabanı yetki reddi üçlüsü tamamlanmış olur.

İki hata kodunu ayırın:

  • •1142: Reddedilme tablo veya görünüm (view) düzeyindedir.
  • •1143: Reddedilme kolon (column) düzeyindedir. Kısıtlı bir kolon (örneğin kredi kartı veya kimlik no) içeren bir sorgu çalıştırdıysanız 1143 alırsınız; tablo genelinde yetki aramak yanlış yönde zaman kaybettirir.
ÖNEMLİ
MySQL'in Hesap Kimliği Mimarisi: `kullanıcı@host` Çifti MySQL'de bir hesap tek başına app değil, `'app'@'host'` çiftidir. 'app'@'localhost' ile 'app'@'10.0.2.%' tamamen iki ayrı hesaptır ve yetki tablolarında ayrı satırlarda yaşarlar. "Kullanıcıya yetki verdim ama hâlâ hata alıyor" şikâyetinin %90 nedeni, yetkinin istemcinin bağlandığı gerçek host tanımına verilmemiş olmasıdır.

▸Nedenini Doğrulayan En Değerli İki Satır

sql
SELECT USER() AS gonderilen_kimlik, CURRENT_USER() AS eslesen_hesap;
  • •`USER()`: İstemci uygulamasının MySQL'e bağlanırken talep ettiği kullanıcı ve geldiği kaynak IP adresidir.
  • •`CURRENT_USER()`: MySQL yetki motorunun (ACL) kuralları tarayarak istemciyi fiilen eşleştirdiği hesaptır.

İkisi birbirinden farklıysa sorun yetki listesinde değil, hesap eşleşmesindedir! Örneğin USER() app@10.0.2.15 derken CURRENT_USER() app@% dönebilir. Siz gidip spesifik 'app'@'10.0.2.15' hesabına yetki verdiyseniz, MySQL daha genel olan 'app'@'%' hesabını eşleştirdiği için yetkiniz hiçbir şekilde devreye girmez!

Etkin Yetkileri Listeleme

sql
SHOW GRANTS FOR CURRENT_USER(); SHOW GRANTS FOR 'app'@'10.0.2.%';

▸Dört Yetki Katmanı ve MySQL 8 Rol Tuzağı

1. Host Bazlı Hesap Önceliği

MySQL bağlantı anında en dar host maskesinden en geniş maskeye doğru (localhost → IP → CIDR → %) sıralama yapar. Geniş bir % tanımı daha özel bir tanımı gölgeleyebilir.

2. Kolon Düzeyi Yetki Tuzağı

Bir kullanıcıya sadece UPDATE yetkisi verip SELECT vermezseniz, şu sorgu anında patlar:

sql
UPDATE siparis SET durum = 'iptal' WHERE tutar = 0;

Sorgunun WHERE tutar = 0 filtresini değerlendirebilmesi için tutar kolonu üzerinde SELECT yetkisi zorunludur.

3. MySQL 8 Rol Tuzağı: Yetki Var Ama Etkin Değil!

MySQL 8.0 ile roller geldi:

sql
GRANT r_okuyucu TO 'app'@'10.0.2.%';

Bu komut yetkiyi verir, ancak rolü etkinleştirmez! Oturum açıldığında rol etkin değilse:

sql
SELECT CURRENT_ROLE(); -- Boş döner (NONE)!

SHOW GRANTS çıktısında rol görünmesine rağmen kullanıcı SELECT yapamaz ve 1142 alır.


▸Adım Adım Kalıcı Çözüm

1. Doğru Hesaba Doğru Kapsamda Yetki Verin

sql
GRANT SELECT ON app.siparis TO 'app'@'10.0.2.%';

2. FLUSH PRIVILEGES Şehir Efsanesini Bırakın

GRANT ve REVOKE komutları MySQL bellek içi yetki önbelleğini anında günceller; ardından FLUSH PRIVILEGES çalıştırmak tamamen gereksizdir. Bu komut yalnızca mysql.user tablosunu doğrudan INSERT/UPDATE ile değiştirdiğinizde gereklidir.

3. Rolleri Otomatik Olarak Etkinleştirin (SET DEFAULT ROLE)

MySQL 8 kullanıyorsanız verilen rolleri varsayılan yapın:

sql
CREATE ROLE r_okuyucu; GRANT SELECT ON app.* TO r_okuyucu; GRANT r_okuyucu TO 'app'@'10.0.2.%'; -- Kritik Adım: SET DEFAULT ROLE ALL TO 'app'@'10.0.2.%';

Artık kullanıcı bağlandığı anda rolü otomatik olarak devralır ve 1142 almaz.


▸İlgili Hata Rehberleri & Hub Bağlantıları

Diğer Veritabanı Hata Teşhisleri

Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.

Tüm Hatalar (50)