MariaDB'de en sık karşılaşılan hatalar ve ilk bakılacak yer şöyle özetlenebilir: 1045 ve 1698 giriş reddidir (parola, hesap veya unix_socket sorunu), 1064 sözdizimi hatasıdır ve near sözcüğünden sonraki metne bakılır, 1062 benzersiz anahtarda tekrar eden değerdir, 1146 bulunamayan tablodur, 1205 kilit bekleme süresinin dolmasıdır, 1213 deadlock'tur ve 2002/2003 istemcinin sunucuya hiç ulaşamadığını gösterir. Sunucu hiç başlamıyorsa neden neredeyse her zaman hata günlüğüne yazılmıştır.

Bu yazı her hata için belgelerin anlattığı olası nedenleri ve çözüm adımlarını Türkçe olarak bir araya getirir. Hata mesajlarını resmî hata kodu sayfalarında ve hızlı başlangıç rehberlerinde geçtiği haliyle veriyoruz; kendi sisteminizde tablo, kullanıcı veya dosya adları farklı olacaktır. Hata kodunun yanındaki beş karakterlik değer (örneğin 28000) SQLSTATE kodudur ve uygulamaların hatayı sınıflandırmak için kullandığı standart koddur. Bağlantı katmanındaki hatalar için uzaktan bağlantı yazısı ve kimlik doğrulama yazısı daha ayrıntılı bilgi verir.

Hızlı başvuru tablosu

Hızlı başvuru tablosu: 1045, 1698, 1064, 1062
KodSQLSTATEMesajın özüİlk kontrol
104528000Access denied for user ... (using password: YES/NO)Parola, hesap ve host eşleşmesi, anonim hesap
169828000Access denied for user ... (using password kısmı yok)unix_socket kimlik doğrulaması; sudo mariadb
106442000You have an error in your SQL syntax ... near ... at linenear sonrasındaki metin, ayraç, ayrılmış kelime
106223000Duplicate entry ... for keyBenzersiz index, collation
114642S02Table ... doesn't existVeritabanı adı, büyük/küçük harf, mariadb-upgrade
1205HY000Lock wait timeout exceeded; try restarting transactionKilidi tutan açık transaction
121340001Deadlock found when trying to get lock; try restarting transactionTransaction'ı yeniden dene, erişim sırası
2002 / 2003HY000Can't connect to local server / Can't connect to serverSunucu çalışıyor mu, soket, port, ağ

ERROR 1045: Access denied for user (using password)

Sunucu bu hatayı bir giriş kimlik doğrulamasından geçemediğinde döndürür. Mesaj neyin yanlış olduğunu söylemez: yanlış parola, eksik parola ve hiç hesabı olmayan bir kullanıcı adı aynı hatayı verir. using password: YES yalnızca istemcinin bir parola gönderdiğini, doğru olduğunu değil; using password: NO ise hiç parola gönderilmediğini anlatır. Belgelerdeki örnek:

text
mariadb -u app -pwrong
ERROR 1045 (28000): Access denied for user 'app'@'localhost' (using password: YES)
mariadb -u app
ERROR 1045 (28000): Access denied for user 'app'@'localhost' (using password: NO)

Çözüm adımları şöyledir. Önce parolayı kontrol edin; using password: NO görüyorsanız istemcinin gerçekten parola gönderdiğinden emin olun, örneğin mariadb komutunu -p ile çağırın ya da uygulamanın bağlantı ayarlarına parolayı ekleyin. İkinci olarak, hata mesajındaki kullanıcı ve host için bir hesap olup olmadığına mysql veritabanına erişimi olan bir kullanıcıyla bakın. Belgelere göre skip_name_resolve kapalıyken 127.0.0.1 adresine yapılan TCP bağlantısı da localhost olarak raporlanır.

sql
SELECT User, Host, plugin FROM mysql.user WHERE User='app';

Üçüncü olarak anonim hesaplara bakın. Sunucu en belirgin host eşleşmesini önce seçtiği için yerel bir bağlantıda ''@'localhost' hesabı 'app'@'%' hesabının önüne geçer; giriş doğru parolayla bile bu hatayla başarısız olur, parolasız denemede ise anonim hesap olarak başarılı olur. mariadb-install-db, --skip-test-db ile çalıştırılmadıkça test veritabanıyla birlikte localhost ve sunucunun host adı için anonim hesaplar oluşturur. Bunları DROP USER ile ya da mariadb-secure-installation ile kaldırabilirsiniz.

sql
DROP USER ''@'localhost';

Karıştırılan komşu hatalar da var: istemcinin host'u hiçbir hesapla eşleşmiyorsa sunucu kullanıcı adına bakmadan 1130 döndürür; giriş başarılı olur ama bağlantıda adı verilen veritabanı için yetki yoksa hata 1044 olur; kilitli bir hesap yanlış parolada yine 1045 verir. Her başarısız giriş Access_denied_errors durum değişkeninde sayılır ve varsayılan log_warnings değeri 2 veya üzerinde olduğundan hata günlüğüne de bir uyarı satırı olarak düşer. Hesap oluşturma ve host kısmının anlamı için CREATE USER yazısına, yetkiler için GRANT ve REVOKE yazısına bakın.

ERROR 1698: root ile sudo olmadan bağlanamamak

1698, parola kullanmayan kimlik doğrulamalar için 1045'in karşılığıdır ve mesajında using password kısmı bulunmaz. En sık nedeni unix_socket eklentisidir: hesap belirli bir işletim sistemi kullanıcısını bekler, istemciyi başka bir kullanıcı çalıştırıyorsa komut satırında parola vermek hiçbir şey değiştirmez. mariadb-install-db'nin varsayılan olarak oluşturduğu root@localhost hesabı böyle çalışır.

text
mariadb -u root
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
mariadb -u root -pguess
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

Çözüm, istemciyi hesabın beklediği işletim sistemi kullanıcısıyla çalıştırmaktır; root için bu sudo mariadb demektir. Belgeler bunu kalıcı bir çözüm olarak değil, sunucuya girip uygun bir yönetici ya da uygulama hesabı oluşturmak için tek seferlik bir yol olarak önerir. Hesaba ek bir kimlik doğrulama yöntemi olarak parola eklemek de mümkündür; bunun yolu unix_socket ve ed25519 yazısında, unutulan root parolasının sıfırlanması ise root şifresi sıfırlama yazısında anlatılıyor. Aynı kod, ADMIN OPTION olmadan bir rol vermeye çalışmak gibi bazı yetki durumlarında da görülebilir.

bash
sudo mariadb

ERROR 1064: SQL sözdizimi hatası

ERROR 1064: SQL sözdizimi hatası

Sunucu ayrıştıramadığı her deyim için 1064 döndürür. Mesaj, ayrıştırıcının durduğu noktadan başlayan metni ve satır numarasını içerir:

text
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELEC 1' at line 1

Hatayı bulmak için near sözcüğünden sonraki metne bakın; hata ya oradadır ya da hemen öncesinde, çoğu zaman o metinden önceki son kelimededir. Sunucu en fazla 80 karakter gösterir ve gerisini ... ile keser. near '' görmek deyimin tamamlanmadan bittiği anlamına gelir: tablo adı olmayan bir SELECT 1 FROM ya da istemci ; karakterini ayraç olarak kullandığı için ilk ; işaretinde kesilen bir saklı yordam gövdesi buna örnektir. Sunucunun verdiği satır numarası deyimin başından sayılır; mariadb istemcisiyle bir betik çalıştırdığınızda istemci, deyimin betikte başladığı satırı ayrıca ekler.

Belgelerin listelediği yaygın nedenler şunlardır. Eksik ayraç: iki deyim arasında ; yoksa hata ikinci deyimin başında yakalanır. Saklı yordamlarda ayraç: BEGIN ... END bloğu içeren bir yordamı komut satırından oluştururken DELIMITER ile geçici olarak farklı bir ayraç seçmeniz gerekir; ayrıntı için stored procedure yazısına bakın. Ayrılmış kelimeler: order gibi bir ayrılmış kelime tırnaksız tablo adı olarak kullanılamaz.

sql
CREATE TABLE order(id INT);
-- 1064 hatası verir; çözümlerden biri ters tırnak kullanmaktır:
CREATE TABLE `order`(id INT);

Ayrılmış kelime listesi sürüme göre değişir. 12.3 ile CONVERSION ve TO_DATE ayrılmış kelime oldu, ACCESSIBLE ise 12.0 öncesinde ayrılmışken artık değil; yükseltmeden sonra aniden çıkan 1064 hataları için 12.3 yenilikleri yazısına bakın. Son yaygın neden SQL_MODE uyumsuzluğudur: örneğin tanımlayıcıları çift tırnakla yazmak yalnızca ANSI_QUOTES açıkken çalışır; aksi halde ters tırnak kullanmalısınız.

ERROR 1062: Duplicate entry for key

Bu hata, benzersiz değer isteyen bir anahtara (UNIQUE veya birincil anahtar) tekrar eden bir değer yazılmaya çalışıldığında oluşur. Mesaj değeri ve index'i adlandırır; birincil anahtar için index adı PRIMARY olur. Belgelerdeki örnekte f sütununda benzersiz index olan bir tabloya 'b' değeri ikinci kez eklenir:

sql
CREATE TABLE t1 (
  id INT AUTO_INCREMENT PRIMARY KEY,
  f VARCHAR(10) UNIQUE
);

INSERT INTO t1 (f) VALUES ('a'),('b');

INSERT INTO t1 (f) VALUES ('b'),('c');
ERROR 1062 (23000): Duplicate entry 'b' for key 'f'

İki değerin tekrar sayılıp sayılmayacağı baytlarına değil sütunun collation'ına bağlıdır. Büyük/küçük harf duyarsız bir collation'da 'B', 'b' ile aynı sayılır; aksan duyarsız bir collation'da 'ä', 'a' ile aynı sayılır; çoğu collation'ın PAD SPACE olması nedeniyle sondaki boşluklar da dikkate alınmaz ve 'b ', 'b' ile çakışır. Bu değerlerin farklı kalması gerekiyorsa sütuna utf8mb4_bin gibi harf ve aksan duyarlı bir collation verin. Türkçe metinlerde collation seçimi için karakter seti ve collation yazısına bakın.

Tekrar beklenen durumlarda deyimi başarısız olmaktan kurtaran üç yol vardır: INSERT IGNORE tekrar eden satırları atlayıp her biri için 1062 kodlu bir uyarı verir, INSERT ... ON DUPLICATE KEY UPDATE mevcut satırı günceller, REPLACE ise mevcut satırı silip yenisini ekler. Bu deyimlerin farkları INSERT, UPDATE ve DELETE yazısında anlatılıyor. Belgelerin iki ek notu var: türünün en büyük değerine ulaşmış bir AUTO_INCREMENT sütunu bu hatayı değil 167 numaralı Out of range value for column hatasını verir; bir replikada 1062 ise replikaya doğrudan yazılmış bir satır yüzünden replikasyonu durdurabilir ve olayı atlamadan önce satırın neden orada olduğunu bulmanız gerekir.

ERROR 1146: Table doesn't exist

Mesajın kalıbı Table '%s.%s' doesn't exist biçimindedir; yani hata, veritabanı adıyla birlikte tam tablo adını gösterir. Belgelerin bu kod için ayrı bir çözüm metni yoktur, ancak ilgili sayfalar üç yaygın durumu açıklar. Birincisi yanlış veritabanıdır: mesajdaki veritabanı adının, tablonun gerçekten bulunduğu veritabanı olup olmadığını kontrol edin.

İkincisi büyük/küçük harf duyarlılığıdır. MariaDB veritabanlarını dizin, tabloları dosya olarak sakladığı için büyük/küçük harfe duyarlı dosya sistemlerinde, yani Unix tabanlı sistemlerde, Musteri ile musteri farklı tablolardır. lower_case_table_names değişkeni Unix'te varsayılan olarak 0'dır ve adlar harfe duyarlı karşılaştırılır; Windows'ta varsayılan 1'dir. Windows'ta geliştirip Linux sunucuya taşınan uygulamalarda 1146 hatasının sık nedeni budur. Bu değişken veritabanı başlatma parametresidir ve mariadb-install-db çalıştırılmadan önce ayarlanmalıdır; sonradan değiştirmek davranışı beklendiği gibi değiştirmez. Harfe duyarsız sistemlerde bile aynı deyim içinde tabloya tutarlı biçimde aynı harflerle başvurmanız gerekir.

sql
SELECT @@lower_case_table_names;
SHOW TABLES;

Üçüncüsü sistem tablolarıdır. Geçiş sırasında Table 'mysql.user' doesn't exist görüyorsanız belgelere göre mariadb-upgrade adımı atlanmıştır. Sunucu başlarken Can't open privilege tables: Table 'mysql.host' doesn't exist görüyorsanız sistem tabloları eksik ya da yanlış yerdedir; bu durum özellikle seçenek dosyaları basedir veya datadir değerini standart dışı bir yere ayarlamışken yeni sunucu varsayılan konumu kullandığında yükseltmelerden sonra görülür. Önce bu değişkenlerin doğru ayarlandığını kontrol edin; tablolar gerçekten yoksa mariadb-install-db ile oluşturmanız gerekebilir. Yükseltme adımları için sürüm yükseltme yazısına bakın.

ERROR 1205: Lock wait timeout exceeded

Deyim, başka bir transaction'ın tuttuğu bir kilidi beklemiş ve süre dolunca vazgeçmiştir. İki tür kilit ve iki ayrı süre vardır. Satır kilitlerinde InnoDB, innodb_lock_wait_timeout saniye (varsayılan 50) bekler. ALTER TABLE gibi deyimlerin beklediği metadata kilitlerinde ise süre lock_wait_timeout ile belirlenir ve varsayılanı bir gündür. NOWAIT kullanan bir deyim aynı hatayı hemen, WAIT n kullanan ise n saniye sonra alır.

Varsayılan olarak yalnızca süresi dolan deyim geri alınır; transaction önceki değişiklikleriyle açık kalır ve sizin commit veya rollback etmeniz gerekir. innodb_rollback_on_timeout açıksa InnoDB tüm transaction'ı geri alır. Çözüm için kilidi tutan transaction'ı bulun: SHOW ENGINE INNODB STATUS açık transaction'ları listeler, INFORMATION_SCHEMA.INNODB_TRX tablosu ise her birinin ne kadar süredir çalıştığını gösterir. Çoğu zaman suçlu, bir transaction başlatıp hiç commit etmeyen, örneğin autocommit kapalı bir istemcidir. O transaction'ı bitirin ya da oturumu KILL ile sonlandırın.

sql
SHOW ENGINE INNODB STATUS\G
SELECT * FROM information_schema.INNODB_TRX\G
KILL 1234;

Son satırdaki 1234 yalnızca yer tutucudur; gerçek bağlantı numarasını SHOW PROCESSLIST çıktısından alırsınız (SHOW PROCESSLIST ve KILL yazısı). Kalıcı önlemler olarak belgeler transaction'ları kısa tutmayı, transaction açıkken kullanıcı girdisi beklememeyi, deyimlerin daha az satır kilitlemesi için index eklemeyi, uygulamada yeniden denemeyi ve kilitli satırları beklemek yerine atlamak için SKIP LOCKED kullanmayı önerir. Süreyi artırmak yalnızca toplu işler gibi uzun beklemelerin beklendiği durumlar için önerilir.

ERROR 1213: Deadlock found when trying to get lock

İki veya daha fazla transaction, diğerlerinin tuttuğu kilitleri beklediği için hiçbiri ilerleyemez. Belgelerin örneğinde bir transaction önce 1. satırı sonra 2. satırı, diğeri önce 2. satırı sonra 1. satırı günceller. InnoDB deadlock'u hemen fark eder, transaction'lardan birini geri alır ve bu hatayı ona döndürür; diğerleri devam eder. 1205'ten önemli farkı şudur: burada yalnızca son deyim değil, transaction'ın tamamı geri alınır. Belgeler deadlock'un bir sunucu arızası olmadığını, eşzamanlı transaction çalıştıran her uygulamada olabileceğini vurgular.

Normal çözüm transaction'ın tamamını yeniden denemektir ve uygulama buna hazır olmalıdır. Olasılığı azaltmak için tüm transaction'larda tablolara ve satırlara aynı sırayla erişin, transaction'ları kısa tutun, index ekleyin (kullanılabilir index'i olmayan bir UPDATE veya DELETE taradığı her satırı kilitler) ve gereken satırları baştan SELECT ... FOR UPDATE ile kilitleyin. Son deadlock'un nedenini SHOW ENGINE INNODB STATUS çıktısındaki LATEST DETECTED DEADLOCK bölümünde görürsünüz; her deadlock'u hata günlüğüne yazdırmak için innodb_print_all_deadlocks değişkenini açabilirsiniz. innodb_deadlock_detect kapalıysa InnoDB deadlock aramaz ve transaction'lar 1205 ile biter. Transaction ve kilit modları için transaction ve izolasyon seviyeleri yazısına bakın.

ERROR 2002 ve 2003: sunucuya ulaşılamıyor

Bu iki kod sunucunun değil istemcinin ürettiği hatalardır ve bağlantının hiç kurulamadığını gösterir. Bağlantı sorunları rehberindeki örnekler:

text
ERROR 2002 (HY000): Can't connect to local MySQL server through
  socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")

ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost'
  (111 "Connection refused")

İlk olası neden sunucunun çalışmıyor olmasıdır; mariadb-admin status ile kontrol edebilir, çalışmıyorsa ortamınıza uygun yöntemle başlatabilirsiniz (systemd yazısı). İkinci neden sunucunun çalışması ama belirtilen host, port, soket veya protokolde dinlememesidir. Unix'te soket dosyasının yolu standart dışı olabilir ya da sunucu ile istemci yapılandırmasında farklı yazılmış olabilir; socket seçeneğinin her iki tarafta aynı değeri taşıdığından emin olun. Çalışan soketi bulmak için belgeler şu komutu önerir:

bash
mariadb-admin status
netstat -ln | grep mysqld

Yerelde bağlanabildiğiniz halde uzaktan bağlanamıyorsanız sorun genellikle MariaDB'nin uzak TCP/IP bağlantılarını kabul etmemesi ya da yalnızca localhost adresine bağlı olmasıdır; telnet ile porta erişimi test edebilir, işletim sistemi hata kodlarını perror ile çözebilirsiniz. bind-address ayarı ve uzak kullanıcılar için uzaktan bağlantı yazısına bakın. Beklemediğiniz parametrelerle bağlanıyorsanız seçenek dosyaları veya MYSQL_HOST gibi ortam değişkenleri devrede olabilir; mariadb --no-defaults ile varsayılan seçenek dosyalarını devre dışı bırakarak deneyebilirsiniz. Web uygulamalarındaki karşılığı için WordPress veritabanı bağlantı hatası rehberine bakın.

Sunucu başlamıyorsa

Sunucu başlamıyorsa: Geçersiz seçenek, Veri dizinine yazılamıyor, İkinci bir örnek çalışıyor, Buffer pool için bellek yok

Başlatma hatasının nedeni neredeyse her zaman hata günlüğüne, sunucuyu elle başlatıyorsanız konsola da yazılır. Varsayılan olarak hata günlüğü host-adı.err adıyla veri dizinine yazılır; yaygın konumlar arasında /var/log/ ve /var/log/mysql bulunur. Günlük ve veri dizininin gerçek yerini ve sunucunun seçenek dosyalarından okuduğu değerleri şu komutlarla görebilirsiniz:

bash
mariadbd --help --verbose | grep 'log-error' | tail -1
mariadbd --help --verbose | grep 'datadir' | tail -1
mariadbd --print-defaults
my_print_defaults --mysqld

Belgelerin listelediği başlıca nedenler ve günlükte görünen ipuçları şöyledir:

  • Geçersiz seçenek: günlükte unknown variable 'option=value' görürsünüz. Yükseltmeden sonra daha sık olur; seçenek adları büyük/küçük harfe duyarlıdır. Seçeneği silin, adını düzeltin veya değerini geçerli bir değerle değiştirin.
  • Veri dizinine yazılamıyor: Can't create test file uyarısı ve ardından Aborting. Tüm veri dizininin mariadbd sürecini çalıştıran kullanıcıya (genellikle mysql) ait olduğundan ve üst dizinlerin herkes için çalıştırma (x) iznine sahip olduğundan emin olun.
  • İkinci bir örnek çalışıyor: Can't lock aria control file veya InnoDB: Unable to lock ./ibdata1 error: 11. Aynı veri dizininde zaten çalışan başka bir MariaDB süreci vardır.
  • Buffer pool için bellek yok: InnoDB: Fatal error: cannot allocate memory for the buffer pool. Sunucuya bellek ekleyin ya da innodb_buffer_pool_size değerini düşürün (buffer pool ayarları).
  • systemd kısıtları: varsayılan birim dosyası ProtectHome=true ve ProtectSystem=full ayarlar; MariaDB /home, /root veya /run/user altındaki dosyalara erişmeye çalışırsa izin hatası alır. Başlatma 90 saniyeden uzun sürerse TimeoutStartSec varsayılanı yüzünden servis başarısız sayılır.
  • SELinux veya AppArmor: standart dışı port veya dosya yolları kullanıyorsanız erişim engellenebilir. Veri dizinini taşıdıysanız AppArmor için takma ad tanımlamanız gerekebilir.
  • Bozuk redo log veya tablo: InnoDB bozulma algıladığında sunucuyu bilerek durdurur; verilerin çoğunu kurtarmak için InnoDB kurtarma modlarıyla başlatıp veriyi dışa aktarmanız gerekebilir.

Yapılandırma dosyalarının hangi sırayla okunduğunu my.cnf yazısında, servis birim dosyasının nasıl genişletileceğini systemd yazısında, günlük ayarlarını ise error log ve slow query log yazısında bulabilirsiniz.

Sık yapılan hatalar

  • using password: YES görünce parolanın doğru olduğunu sanmak: Bu yalnızca bir parola gönderildiğini gösterir.
  • root için 1698 alınca parolayı değiştirmeye çalışmak: unix_socket kullanan hesapta parola kontrol edilmez; sudo mariadb ile girin.
  • 1064'te yalnızca satır numarasına bakmak: Asıl ipucu near sonrasındaki metindir.
  • 1205 sonrası transaction'ı açık bırakmak: Varsayılan olarak yalnızca son deyim geri alınır; transaction'ı siz bitirmelisiniz.
  • 1213 sonrası yalnızca son deyimi tekrarlamak: Deadlock'ta transaction'ın tamamı geri alınır, bütününü yeniden çalıştırın.
  • Windows'tan Linux'a taşırken tablo adı harflerini gözden kaçırmak: Linux'ta tablo adları harfe duyarlıdır.
  • Hata günlüğüne bakmadan sunucuyu tekrar tekrar başlatmak: Neden neredeyse her zaman günlüktedir.

Sık Sorulan Sorular

1045 ile 1698 arasındaki fark nedir?

1045 parola tabanlı bir girişin reddidir ve mesajında using password kısmı vardır. 1698 parola kullanmayan kimlik doğrulamada, çoğunlukla unix_socket ile görülür ve bu kısım yoktur.

Deadlock (1213) hatası sunucuda bir sorun olduğunu mu gösterir?

Hayır. Belgelere göre deadlock eşzamanlı transaction çalıştıran her uygulamada olabilir. Uygulamanın transaction'ı yeniden deneyebilmesi ve erişim sırasının tutarlı olması asıl çözümdür.

innodb_lock_wait_timeout değerini artırmak 1205'i çözer mi?

Yalnızca belirtiyi geciktirir. Belgeler önce kilidi tutan transaction'ı bulup bitirmeyi, transaction'ları kısaltmayı ve index eklemeyi önerir; süreyi artırmak uzun beklemelerin beklendiği toplu işler içindir.

2002 hatasında soket dosyasının yolunu nasıl bulurum?

Belgeler çalışan Unix soketini netstat -ln | grep mysqld ile bulmayı önerir. Bulduğunuz yolun hem sunucu hem istemci yapılandırmasındaki socket seçeneğiyle aynı olması gerekir.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: MariaDB öğrenme rehberi · MariaDB kimlik doğrulama · MariaDB root şifresi sıfırlama · MariaDB transaction · MariaDB uzaktan bağlantı · WordPress veritabanı bağlantı hatası