MySQL Deadlock ERROR 1213: Grafiği Okuma ve Kalıcı Önleme
MySQL "Deadlock found when trying to get lock" — Neden Olur, Nasıl Kalıcı Çözülür?
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
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transactionÖnce şunu netleştirelim: deadlock bir hata değil, InnoDB'nin koruma mekanizmasıdır. İki işlem birbirinin kilidini beklerken döngü oluşur; InnoDB döngüyü tespit eder, kurban seçer ve o işlemi tamamen geri alır. Bu yüzden doğru refleks "deadlock'ı engellemek" değil, "deadlock'a dayanıklı uygulama yazmak" ve ardından oluşum sıklığını azaltmaktır.
▸Grafiği bulma
1. Anlık kayıt:
SHOW ENGINE INNODB STATUS\GÇıktıda LATEST DETECTED DEADLOCK bölümüne bakın. Bu yalnızca son deadlock'ı gösterir.
2. Kalıcı kayıt (bunu açın):
SET GLOBAL innodb_print_all_deadlocks = ON;Artık her deadlock, MySQL hata günlüğüne grafiğiyle birlikte yazılır. Maliyeti ihmal edilebilir, teşhis değeri yüksektir.
3. Bekleyen kilitleri canlı görme:
SELECT w.requesting_engine_transaction_id AS bekleyen,
w.blocking_engine_transaction_id AS bloklayan,
r.trx_query AS bekleyen_sorgu,
b.trx_query AS bloklayan_sorgu,
b.trx_mysql_thread_id AS bloklayan_thread
FROM performance_schema.data_lock_waits w
LEFT JOIN information_schema.innodb_trx r
ON r.trx_id = w.requesting_engine_transaction_id
LEFT JOIN information_schema.innodb_trx b
ON b.trx_id = w.blocking_engine_transaction_id;▸En sık üç neden
1. Ters erişim sırası. Bir işlem A sonra B tablosuna, diğeri B sonra A'ya dokunuyorsa deadlock kaçınılmazdır. Uygulamada sabit bir erişim sırası belirleyin. Kodu düzeltmeden yapılan her parametre değişikliği geçicidir.
2. İndekssiz `WHERE` ve gap lock. REPEATABLE READ izolasyon seviyesinde, indekssiz bir UPDATE/DELETE taranan tüm aralığa gap lock koyar. İki işlem farklı satırları güncellese bile birbirini bekler. Kontrol:
EXPLAIN UPDATE hesaplar SET bakiye = bakiye - 10 WHERE musteri_no = 42;type: ALL ya da rows çok yüksekse, önce indeks ekleyin. Yüksek eşzamanlı OLTP iş yüklerinde READ COMMITTED'a geçmek gap lock kaynaklı deadlock'ların büyük kısmını ortadan kaldırır:
SELECT @@transaction_isolation;3. Uzun işlemler ve toplu güncellemeler. Tek bir UPDATE ile 500.000 satır güncellemek, kilitleri saniyeler boyunca tutar. Toplu işlemleri parçalayın:
UPDATE siparisler SET durum = 'arsiv'
WHERE durum = 'tamamlandi' AND id BETWEEN 1 AND 10000;
-- her partiden sonra COMMIT▸Uygulama tarafında retry tasarımı
Deadlock kurbanı olan işlem tamamen geri alınır; uygulama bunu beklenen bir durum olarak ele almalıdır.
- •Retry yalnızca
1213(deadlock) ve1205(lock wait timeout) için yapılmalı. - •İşlem idempotent olmalı; aksi halde retry çift kayıt üretir.
- •Retry sayısı sınırlı (3-5), bekleme süresi artan (jitter'lı) olmalı.
- •Retry, deadlock'ın oluştuğu *tüm* transaction'ı kapsamalı.
▸İlgili Mühendislik Rehberleri ve İç Linkler
- •MySQL InnoDB Tuning CheatSheet
- •MySQL Lock wait timeout (ERROR 1205) Rehberi
- •MySQL InnoDB Cluster Mimarisi
- •Test edilen sürümler: MySQL 8.0 / 8.4 LTS
MySQL Diğer Üretim Rehberleri
Aynı veritabanı motoruna ait doğrulanmış diğer içerikler.
InnoDB Tuning Referansı
Buffer pool boyutlandırma formülü (%70-80), redo log ve flush politikaları, I/O kapasitesi, production my.cnf şablonu ve SHOW ENGINE INNODB STATUS okuma rehberi.
MySQL Yedekleme & Kurtarma
mysqldump ve MySQL Shell dumpInstance mantıksal yedekler, Percona XtraBackup fiziksel yedekleme, binary log ile PITR ve CLONE eklentisi.
MySQL OCP 8.0 DBA Sınav Konu Haritası
Oracle 1Z0-908 MySQL 8.0 Database Administrator sınavının 7 ana alanı: Mimari, Kurulum, Güvenlik, İzleme, Optimizasyon, Yedekleme, HA (InnoDB Cluster) ve sınav tuzakları.