MySQL'de kilit bekleme zaman aşımı hatası nasıl ayıklanır?


269

Üretim hata günlüklerimde bazen şunu görüyorum:

SQLSTATE [HY000]: Genel hata: 1205 Kilit bekleme zaman aşımı aşıldı; işlemi yeniden başlatmayı dene

Hangi sorgu o anda veritabanına erişmek için çalışıyor biliyorum ama hangi sorgu o kesin anda kilit vardı bulmak için bir yolu var mı?


1
Herkese
Eirik'in

Yanıtlar:


261

Bunu veren şey işlemdir . Açıklamada, sorgunun bir veya daha fazla InnoDB tablosunda en az bir satırı değiştirmeye çalıştığı açıktır.

Sorguyu bildiğiniz için, erişilen tüm tablolar suçlu olmaya adaydır.

Oradan koşabilmelisin SHOW ENGINE INNODB STATUS\G

Etkilenen tabloları görebilmeniz gerekir

Her türlü ek Kilitleme ve Muteks Bilgilerini alırsınız.

İşte müşterilerimden birinden bir örnek:

mysql> show engine innodb status\G
*************************** 1. row ***************************
  Type: InnoDB
  Name:
Status:
=====================================
110514 19:44:14 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 4 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 9014315, signal count 7805377
Mutex spin waits 0, rounds 11487096053, OS waits 7756855
RW-shared spins 722142, OS waits 211221; RW-excl spins 787046, OS waits 39353
------------------------
LATEST FOREIGN KEY ERROR
------------------------
110507 21:41:35 Transaction:
TRANSACTION 0 606162814, ACTIVE 0 sec, process no 29956, OS thread id 1223895360 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
14 lock struct(s), heap size 3024, 8 row lock(s), undo log entries 1
MySQL thread id 3686635, query id 124164167 10.64.89.145 viget updating
DELETE FROM file WHERE file_id in ('6dbafa39-7f00-0001-51f2-412a450be5cc' )
Foreign key constraint fails for table `backoffice`.`attachment`:
,
  CONSTRAINT `attachment_ibfk_2` FOREIGN KEY (`file_id`) REFERENCES `file` (`file_id`)
Trying to delete or update in parent table, in index `PRIMARY` tuple:
DATA TUPLE: 17 fields;
 0: len 36; hex 36646261666133392d376630302d303030312d353166322d343132613435306265356363; asc 6dbafa39-7f00-0001-51f2-412a450be5cc;; 1: len 6; hex 000024214f7e; asc   $!O~;; 2: len 7; hex 000000400217bc; asc    @   ;; 3: len 2; hex 03e9; asc   ;; 4: len 2; hex 03e8; asc   ;; 5: len 36; hex 65666635323863622d376630302d303030312d336632662d353239626433653361333032; asc eff528cb-7f00-0001-3f2f-529bd3e3a302;; 6: len 40; hex 36646234376337652d376630302d303030312d353166322d3431326132346664656366352e6d7033; asc 6db47c7e-7f00-0001-51f2-412a24fdecf5.mp3;; 7: len 21; hex 416e67656c73204e6f7720436f6e666572656e6365; asc Angels Now Conference;; 8: len 34; hex 416e67656c73204e6f7720436f6e666572656e6365204a756c7920392c2032303131; asc Angels Now Conference July 9, 2011;; 9: len 1; hex 80; asc  ;; 10: len 8; hex 8000124a5262bdf4; asc    JRb  ;; 11: len 8; hex 8000124a57669dc3; asc    JWf  ;; 12: SQL NULL; 13: len 5; hex 8000012200; asc    " ;; 14: len 1; hex 80; asc  ;; 15: len 2; hex 83e8; asc   ;; 16: len 4; hex 8000000a; asc     ;;

But in child table `backoffice`.`attachment`, in index `PRIMARY`, there is a record:
PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 30; hex 36646261666133392d376630302d303030312d353166322d343132613435; asc 6dbafa39-7f00-0001-51f2-412a45;...(truncated); 1: len 30; hex 38666164663561652d376630302d303030312d326436612d636164326361; asc 8fadf5ae-7f00-0001-2d6a-cad2ca;...(truncated); 2: len 6; hex 00002297b3ff; asc   "   ;; 3: len 7; hex 80000040070110; asc    @   ;; 4: len 2; hex 0000; asc   ;; 5: len 30; hex 416e67656c73204e6f7720436f6e666572656e636520446f63756d656e74; asc Angels Now Conference Document;;

------------
TRANSACTIONS
------------
Trx id counter 0 620783814
Purge done for trx's n:o < 0 620783800 undo n:o < 0 0
History list length 35
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, process no 29956, OS thread id 1192212800
MySQL thread id 5341758, query id 189708501 127.0.0.1 lwdba
show innodb status
---TRANSACTION 0 620783788, not started, process no 29956, OS thread id 1196472640
MySQL thread id 5341773, query id 189708353 10.64.89.143 viget
---TRANSACTION 0 0, not started, process no 29956, OS thread id 1223895360
MySQL thread id 5341667, query id 189706152 10.64.89.145 viget
---TRANSACTION 0 0, not started, process no 29956, OS thread id 1227888960
MySQL thread id 5341556, query id 189699857 172.16.135.63 lwdba
---TRANSACTION 0 620781112, not started, process no 29956, OS thread id 1222297920
MySQL thread id 5341511, query id 189696265 10.64.89.143 viget
---TRANSACTION 0 620783736, not started, process no 29956, OS thread id 1229752640
MySQL thread id 5339005, query id 189707998 10.64.89.144 viget
---TRANSACTION 0 620783785, not started, process no 29956, OS thread id 1198602560
MySQL thread id 5337583, query id 189708349 10.64.89.145 viget
---TRANSACTION 0 620783469, not started, process no 29956, OS thread id 1224161600
MySQL thread id 5333500, query id 189708478 10.64.89.144 viget
---TRANSACTION 0 620781240, not started, process no 29956, OS thread id 1198336320
MySQL thread id 5324256, query id 189708493 10.64.89.145 viget
---TRANSACTION 0 617458223, not started, process no 29956, OS thread id 1195141440
MySQL thread id 736, query id 175038790 Has read all relay log; waiting for the slave I/O thread to update it
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (write thread)
Pending normal aio reads: 0, aio writes: 0,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
519878 OS file reads, 18962880 OS file writes, 13349046 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 6.25 writes/s, 4.50 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 1190, seg size 1192,
174800 inserts, 174800 merged recs, 54439 merges
Hash table size 35401603, node heap has 35160 buffer(s)
0.50 hash searches/s, 11.75 non-hash searches/s
---
LOG
---
Log sequence number 28 1235093534
Log flushed up to   28 1235093534
Last checkpoint at  28 1235091275
0 pending log writes, 0 pending chkp writes
12262564 log i/o's done, 3.25 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 18909316674; in additional pool allocated 1048576
Dictionary memory allocated 2019632
Buffer pool size   1048576
Free buffers       175763
Database pages     837653
Modified db pages  6
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 770138, created 108485, written 7795318
0.00 reads/s, 0.00 creates/s, 4.25 writes/s
Buffer pool hit rate 1000 / 1000
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread process no. 29956, id 1185823040, state: sleeping
Number of rows inserted 6453767, updated 4602534, deleted 3638793, read 388349505551
0.25 inserts/s, 1.25 updates/s, 0.00 deletes/s, 2.75 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

1 row in set, 1 warning (0.00 sec)

İnnodb_lock_wait_timeout ayarlayarak InnoDB için kilit bekleme zaman aşımı değerini artırmayı düşünmelisiniz , varsayılan değer 50 saniyedir

mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50    |
+--------------------------+-------+
1 row in set (0.01 sec)

/etc/my.cnfBu hat ile kalıcı olarak daha yüksek bir değere ayarlayabilirsiniz

[mysqld]
innodb_lock_wait_timeout=120

ve mysql'yi yeniden başlatın. Şu anda mysql'yi yeniden başlatamıyorsanız, şunu çalıştırın:

SET GLOBAL innodb_lock_wait_timeout = 120; 

Ayrıca oturum süreniz için de ayarlayabilirsiniz

SET innodb_lock_wait_timeout = 120; 

ardından sorgunuz


5
Yerleşik InnoDB için innodb_lock_wait_timeoutdeğişken yalnızca sunucu başlangıcında ayarlanabilir. InnoDB Eklentisi için başlangıçta ayarlanabilir veya çalışma zamanında değiştirilebilir ve hem genel hem de oturum değerlerine sahiptir.
Timo Huovinen

1
Merhaba @rolandomysqldba, lütfen bu
yazımda

2
İlk sorguyu çalıştırmaya çalışırken bu hatayı alıyorum:SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\G' at line 1
Iulian Onofrei

1
@Pacerier mysqld her yeniden başlatıldığında SET GLOBAL innodb_lock_wait_timeout = 120;tekrar çalıştırmanız gerekir . /etc/my.cnfSeçenek varsa , innodb_lock_wait_timeoutsizin için ayarlanır. Herkes herkes için (küresel değiştirmek SÜPER ayrıcalığa sahip dev.mysql.com/doc/refman/5.6/en/... )
RolandoMySQLDBA

3
@IulianOnofrei \ G karakteri MySQL komut satırının özel bir özelliğidir ve çıktının görüntülenme şeklini değiştirir. Diğer MySQL istemcileri için bunun yerine normal bir noktalı virgül kullanın.
thenickdude

83

Birisi bu sorunla ilgili birçok SO iş parçacıklarından birinde belirtildiği gibi: Bazen tabloyu kilitleyen işlem, işlem listesinde uyku olarak görünür! Söz konusu veritabanında açık olan tüm uyku ipliklerini öldürene kadar saçlarımı yırtıyordum (hiçbiri o zaman aktif değildi). Sonunda tablo kilidini açtı ve güncelleme sorgusunun çalışmasına izin verdi.

Yorum yapan kişi, "Bazen bir MySQL iş parçacığı bir tabloyu kilitler, sonra MySQL ile ilgili olmayan bir şeyin olmasını beklerken uyur."

show engine innodb statusGünlüğü yeniden inceledikten sonra (kilitten sorumlu istemciyi izledikten sonra), söz konusu sıkışmış iş parçacığının işlem listesinin en altında, hataya neden olan etkin sorguların altında listelendiğini fark ettim dondurulmuş kilit nedeniyle dışarı:

------------------
---TRANSACTION 2744943820, ACTIVE 1154 sec(!!)
2 lock struct(s), heap size 376, 2 row lock(s), undo log entries 1
MySQL thread id 276558, OS thread handle 0x7f93762e7710, query id 59264109 [ip] [database] cleaning up
Trx read view will not see trx with id >= 2744943821, sees < 2744943821

("Trx okuma görünümü" iletisinin dondurulmuş kilitle ilgili olup olmadığından emin değilsiniz, ancak diğer etkin işlemlerden farklı olarak, bu, yayınlanan sorguyla görünmez ve bunun yerine işlemin "temizlendiğini", ancak birden çok sıra kilitleri)

Hikayenin ahlakı, bir işlemin iş parçacığı uyurken bile aktif olabileceğidir .


2
Hayatımı kurtardığını söyleyemem, ama fikrimi kesin olarak barışa bağladın. Cevabınızı okurken, 3260 saniye boyunca aktif olan ve hiçbir yerde görünmeyen ürpertici bir iplik buldum. öldürdükten sonra tüm problemlerim çözüldü!
kommradHomer

Bu benim sorunumdu. Rails uygulamasındaki Gecikmeli İşin düzgün çalışmasını engelleyen 20.000 saniyelik bir uyku işlemi. Teşekkürler @Eirik
bigtex777

Uyku işleminin neden öldürülmediğine dair bir fikrin var mı? Mesela, bir işlemin tamamlanması gereken bir zaman aşımı var mı?
patrickdavey

1
İşlemleri kilitleme aramanızda yardımcı olabilecek diğer komutlar: show processlist;yürütülmekte olan işlemlerin kapsamlı bir listesini göstermek için, bu da yoğunlaştırılmış bir sürümü olduğu için güzel show engine innodb status\g. Ayrıca, db bir Amazon RDS örneğinde ise, CALL mysql.rds_kill(<thread_id>);konuları öldürmek için kullanabilirsiniz . Sanırım daha yüksek izinleri var, çünkü kill <thread_id>;
düzden

1
Herkes bunun için bir kaynak var - belki COMMIT aşamasından önce kilitler yerleştirildiğini belirten bir belge sayfası? Bu sorunu görmeme rağmen hiçbir şey bulamadım ve kilitleri tutan uyku ipliğini öldürerek giderildi.
Erin Schoonover

42

MySQL'in popülaritesi nedeniyle, Kilit bekleme zaman aşımının aşılması şaşırtıcı değildir ; işlem istisnasını yeniden başlatmayı deneyin SO çok dikkat çekiyor.

Ne kadar fazla çekişmeniz varsa, bir DB motorunun kilitli işlemlerden birini zaman aşımı ile çözeceği kilitlenme olasılığı artar. Ayrıca, (örneğin değiştirdiniz uzun süren işlemler UPDATEveya DELETE) (açıklandığı gibi önlemek kirli-yazma anomaliye kilitleri almak girdileri çok sayıda Yüksek Performanslı Java Persistence kitabı) daha muhtemel diğer işlemlerle çatışmaları üretilmesi içindir.

InnoDB MVCC olmasına rağmen, yine de FOR UPDATEyan tümcesi kullanarak açık kilitler isteyebilirsiniz . Ancak, diğer popüler DB'lerin (Oracle, MSSQL, PostgreSQL, DB2) aksine, MySQL varsayılan yalıtım seviyesi olarak kullanırREPEATABLE_READ .

Artık, aldığınız kilitler (satırları değiştirerek veya açık kilitleme kullanarak), o anda çalışan işlem boyunca tutulur. Kilitleme arasındaki REPEATABLE_READve READ COMMITTEDkilitleme ile ilgili farkın iyi bir açıklamasını istiyorsanız , lütfen bu Percona makalesini okuyun .

REPEATABLE READ'de, bir işlem sırasında edinilen her kilit işlem süresince tutulur.

TAMAMLANDI OKUYUN'da, tarama ile eşleşmeyen kilitler STATEMENT tamamlandıktan sonra serbest bırakılır.

...

Bu, READ COMMITTED'de diğer işlemlerin, UPDATE deyimi tamamlandığında güncelleyemeyecekleri (REPEATABLE READ içinde) satırları güncellemekte serbest oldukları anlamına gelir.

Bu nedenle: İzolasyon seviyesi ( REPEATABLE_READ, SERIALIZABLE) ne kadar kısıtlayıcı olursa, kilitlenme şansı o kadar artar. Bu "kendi başına" bir mesele değil, bir değiş tokuş.

Sen ile çok iyi sonuçlar elde edebilirsiniz READ_COMMITEDistediğiniz kadar, uygulama düzeyinde kayıp güncelleme önleme mantıksal işlemleri birden HTTP istekleri üzerine bu yayılma kullanırken. İyimser kilitleme yaklaşım hedefleri güncelleştirmeleri kaybetti kullanmak bile gerçekleşebilir SERIALIZABLEyalıtım düzeyini kullanmak için izin vererek kilit çekişme azaltırken READ_COMMITED.


4
Kilit bekleme zaman aşımı kilitlenmeden farklı değil mi? Örneğin, bir iş parçacığı meşru nedenlerle 60 saniye boyunca kilit tutarsa, kilit bekleme zaman aşımı oluşabilir. Gerçekten bir kilitlenme varsa, MySQL bunu algılayacak ve bir işlemi anında öldürecek ve bu kilit bekleme zaman aşımı ile ilgili değil mi?
ColinM

1
Haklısın. DB, zaman aşımından sonra ölü kilidi algılar ve bir bekleme işlemini öldürür, böylece diğeri başarısız olurken bir işlem kazanır. Ancak bir kilidi ne kadar uzun süre tutarsanız uygulama o kadar az ölçeklenebilir olur. Kilitlenmemiş olsanız bile, uygulama çalışma zamanı davranışınızın serileştirilebilir kısmını artırmaya devam edersiniz.
Vlad Mihalcea

19

Kayıt için kilit bekleme zaman aşımı istisnası, bir kilitlenme olduğunda ve MySQL bunu algılayamadığında da gerçekleşir, bu nedenle zaman aşımına uğrar. Başka bir neden, çözmek / onarmak daha kolay, ancak son derece uzun çalışan bir sorgu olabilir ve ben burada bu durumu açıklamayacağım.

MySQL genellikle iki işlem içinde "düzgün" olarak inşa edilirse kilitlenme ile başa çıkabilir. MySQL daha sonra sadece daha az kilit içeren bir işlemi öldürür / geri alır (daha az satırı etkileyeceğinden daha az önemlidir) ve diğerinin bitmesini sağlar.

Şimdi iki süreç A ve B ve 3 işlem olduğunu varsayalım:

Process A Transaction 1: Locks X
Process B Transaction 2: Locks Y
Process A Transaction 3: Needs Y => Waits for Y
Process B Transaction 2: Needs X => Waits for X
Process A Transaction 1: Waits for Transaction 3 to finish

(see the last two paragraph below to specify the terms in more detail)

=> deadlock 

Bu çok talihsiz bir kurulum çünkü MySQL bir kilitlenme olduğunu göremiyor (3 işleme yayılmış). Yani MySQL'in yaptığı şey ... hiçbir şey! Ne beklediğini bilmediği için sadece bekler. İlk edinilen kilit zaman aşımını geçene kadar bekler (İşlem A İşlem 1: Kilitler X), bu işlem İşlem 2'nin kilidini açan Kilit X'in kilidini açar.

Teknik, ilk kilide neyin (hangi sorgu) neden olduğunu bulmaktır (Kilit X). show engine innodb statusİşlem 3'ün İşlem 2'yi beklediğini ( ) kolayca görebileceksiniz , ancak İşlem 2'nin hangi işlemi beklediğini göremeyeceksiniz (İşlem 1). MySQL, İşlem 1 ile ilişkili herhangi bir kilit veya sorgu yazdırmaz. Tek ipucu, işlem listesinin ( show engine innodb statusçıktısının) en alt kısmında, İşlem 1'in görünüşte hiçbir şey yapmadığını göreceksiniz (ancak aslında İşlem 3'ün bitiş).

Bekleyen belirli bir işlem için hangi SQL sorgusunun kilidin (Kilit X) verilmesine neden olduğunu bulma tekniği burada açıklanmıştır Tracking MySQL query history in long running transactions

Sürecin ve işlemin tam olarak örnekte ne olduğunu merak ediyorsanız. İşlem bir PHP işlemidir. İşlem, innodb-trx-table tarafından tanımlanan bir işlemdir . Benim durumumda, iki PHP işlemi vardı, her birinde elle bir işlem başlattım. İşin ilginç tarafı, bir işlemde bir işleme başlamış olmama rağmen, MySQL'in dahili olarak iki ayrı işlem kullandığıydı (neden bir fikrim yok, belki bazı MySQL geliştiricileri açıklayabilir).

MySQL kendi işlemlerini dahili olarak yönetiyor ve (benim durumumda) PHP işleminden gelen tüm SQL isteklerini (Process A) işlemek için iki işlem kullanmaya karar verdi. İşlem 1'in İşlem 3'ün bitmesini beklediği ifadesi dahili bir MySQL olayıdır. MySQL, İşlem 1 ve İşlem 3'ün aslında bir "işlem" isteğinin parçası olarak (Proses A'dan) "bilindiğini" biliyordu. İşlem 3 ("işlem" in bir alt bölümü) engellendiği için artık "işlem" in tamamı engellendi. Çünkü "işlem" İşlem 1'i ("işlem" in bir alt bölümü) bitiremediğinden de bitmemiş olarak işaretlendi. "İşlem 1, İşlem 3'ün bitmesini bekliyor" ile kastettiğim budur.


14

Bu istisna ile ilgili en büyük sorun, genellikle bir test ortamında çoğaltılamaz ve biz prod olduğunda innodb motor durumunu çalıştırmak için etrafında değildir. Projelerden birinde bu istisna için aşağıdaki kodu bir catch bloğuna koydum. Bu, istisna olduğunda motor durumunu yakalamama yardımcı oldu. Bu çok yardımcı oldu.

Statement st = con.createStatement();
ResultSet rs =  st.executeQuery("SHOW ENGINE INNODB STATUS");
while(rs.next()){
    log.info(rs.getString(1));
    log.info(rs.getString(2));
    log.info(rs.getString(3));
}

11

pt-deadlock-loggerYardımcı programın kılavuz sayfasına bir göz atın :

brew install percona-toolkit
pt-deadlock-logger --ask-pass server_name

engine innodb statusYukarıda belirtilenlerden bilgi alır ve ayrıca daemonher 30 saniyede bir çalışan bir bilgi oluşturmak için kullanılabilir .



Kilit bekleme zaman aşımları deadlock ile aynı değildir, özellikle innodb onlar hakkında herhangi bir bilgi göstermez çünkü deadlock algılanmaz, bu yüzden pt-deadlock-logger herhangi bir yardım olduğunu düşünmüyorum.
Jay Paroline

Kilit zaman aşımları ve kilitlenmeler birbiriyle ilişkilidir - bkz. Dev.mysql.com/doc/refman/5.7/en/innodb-deadlock-detection.html
Andrei Sura

11

Yukarıdaki Rolando'nun cevabından ötürü, sorgunuzu engelleyen bunlar:

---TRANSACTION 0 620783788, not started, process no 29956, OS thread id 1196472640
MySQL thread id 5341773, query id 189708353 10.64.89.143 viget

Sorgunuzu yürütmeniz gerekiyorsa ve diğerlerinin çalışmasını bekleyemiyorsanız, MySQL iş parçacığı kimliğini kullanarak bunları öldürün:

kill 5341773 <replace with your thread id>

(mysql içinden, kabuktan değil, açıkçası)

İş parçacığı kimliklerini aşağıdakilerden bulabilirsiniz:

show engine innodb status\G

komutunu verin ve veritabanını engelleyen hangisi olduğunu belirleyin.


1
Nereden biliyorsun 5341773? Bunu diğerlerinden ayıran şeyi görmüyorum.
Wodin

Hayır, muhtemelen o threadID değil, bir örnekti. "Show engine innodb status \ G" komutundan iş parçacığı kimliklerini bulmanız ve veritabanını engelleyen hangisinin olduğunu bulmanız gerekir.
Ellert van Koperen

1
Teşekkürler. Yani başka bir deyişle hangisinin tek tek öldürülmeden hangisinin olduğunu söylemenin bir yolu yok mu?
Wodin

İşlemler listesinde hangilerinin ne kadar sürdüğünü görebilirsiniz. Bu yüzden onları tek tek öldürmeye gerek yok, bu liste genellikle neler olup bittiğine dair oldukça iyi bir fikir verir.
Ellert van Koperen

10

Sonuçta ne "diğer sorgu" kilit zaman aşımı sorununa neden olduğunu anlamak için ne yapmak zorunda. Uygulama kodunda, bekleyen tüm veritabanı çağrılarını bu göreve ayrılmış ayrı bir iş parçacığında izleriz. Herhangi bir DB çağrısı N saniyeden uzun sürerse (bizim için 30 saniyedir) günlüğe kaydederiz:

-- Pending InnoDB transactions
SELECT * FROM information_schema.innodb_trx ORDER BY trx_started; 

-- Optionally, log what transaction holds what locks
SELECT * FROM information_schema.innodb_locks;

Yukarıdakilerle, kilitlenmeye neden olan satırları kilitleyen eşzamanlı sorguları tespit edebildik. Benim durumumda, INSERT ... SELECTdüz SELECT'lerin aksine alttaki satırları kilitleyen ifadelerdi . Daha sonra kodu yeniden düzenleyebilir veya okunmamış okuma gibi farklı bir işlem yalıtımı kullanabilirsiniz.

İyi şanslar!


9

Kullanabilirsiniz:

show full processlist

MySQL'deki tüm bağlantıları ve geçerli bağlantı durumunu ve yürütülmekte olan sorguyu listeleyecektir. Ayrıca show processlist;kesilen sorguyu ve bağlantı istatistiklerini görüntüleyen daha kısa bir varyant da vardır .



-2

MySQL general.log'u (disk yoğun) etkinleştirin ve uzun süreli işlemleri ayıklamak için mysql_analyse_general_log.pl kullanın, örneğin:

--min-duration = innodb_lock_wait_timeout değeriniz

Bundan sonra general.log dosyasını devre dışı bırakın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.