我需要一個專家建議。我的MySQL死鎖場景 - 需要建議
背景 PHP /笨 的mysqli InnoDB表 - fares_table 存儲過程
後端 - 一個cronjob PHP腳本被寫入插入(從服務)/更新數據爲每隔幾分鐘fares_table。 (正常的sql查詢)
前端 - 用戶將能夠讀取這些數據 (該查詢寫入存儲過程的形式,因爲它涉及到許多表的連接,因此我的存儲過程已創建臨時表從fares_table並加入到其它表)
問題
Deadlock found when trying to get lock; try restarting transaction
如果用戶發生在前端絆倒而fares_table正在更新/插入可能會發生死鎖。更新語句發生死鎖
死鎖是由存儲過程試圖等待鎖釋放,同時嘗試使用fares_table 中的select語句創建臨時表而造成的,而後端正在執行插入或更新嘗試等待鎖定發佈。
LATEST DETECTED DEADLOCK
------------------------
110408 9:05:45
*** (1) TRANSACTION:
TRANSACTION 0 203543446, ACTIVE 0 sec, OS thread id 6584 fetching rows
mysql tables in use 2, locked 2
LOCK WAIT 761 lock struct(s), heap size 60736, 30170 row lock(s)
MySQL thread id 86268, query id 135039790 XXXXXXX Copying to t
CREATE TEMPORARY TABLE tmp_tb1 AS SELECT MIN(fare) as cheapest_fare,flighttype origin,destination ....
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 18433 n bits 240 index `PRIMARY` of table `db_name`.`fares_table`
Record lock, heap no 85 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 8025d996; asc % ;; 1: len 6; hex 00000c21d3a9; asc ! ;; 2: len 7; hex 0000000b031
*** (2) TRANSACTION:
TRANSACTION 0 203543465, ACTIVE 0 sec, OS thread id 3080 updating or deleting, thread declared inside
mysql tables in use 1, locked 1
3 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1
MySQL thread id 85631, query id 135039816 XXXXX Updating
UPDATE `fares_table` SET `fare` = 2552.85, `currency` = 'AUD'..
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 18433 n bits 240 index `PRIMARY` of table `db_name`.`fares_table`
Record lock, heap no 85 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 8025d996; asc % ;; 1: len 6; hex 00000c21d3a9; asc ! ;; 2: len 7; hex 0000000b031
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 2086 n bits 600 index `flighttype_idx` of table `db_name`.`fares_table`
Record lock, heap no 218 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 7; hex 4f6e6520776179; asc One way;; 1: len 3; hex 424e45; asc BNE;; 2: len 8; hex 8000124a588
*** WE ROLL BACK TRANSACTION (2)
我臨時的解決辦法
捕捉數據庫錯誤1213並重試更新查詢。它現在可以工作,但我想找到一個更好的防止死鎖的解決方案。 任何專業建議?
我要如何改變,以防止死鎖或將複製的flighttype_idx
有助於指數?
它引起我注意時是否創建臨時表的使用是否正確。該存儲過程是從創建選擇fares_table(X鎖)一個不是Temptable 而另一位用戶也碰到網站做同樣的存儲過程(創建fare_tables一個臨時表), 這裏等待鎖被釋放。同時,後端需要更新一行/另一個用戶執行存儲的proc - >導致死鎖?我可以總結這些同時造成更高的死鎖機會嗎?如何使用鎖定防止這種僵局?對於請求相同鎖的其他查詢是否會影響性能? – flyclassic 2011-04-12 06:56:39
也許找到沒有創建臨時表的解決方案?比您所經歷的更復雜的模式成功運行,d/b爭用少得多。重新思考模式以最大限度地選擇數據並儘量減少寫入數據。 – wallyk 2011-04-12 07:49:09
我在困難的情況下,因爲我用存儲過程內部存儲過程使用加入和分組。這種方式的代碼是可重複使用和可維護的。沒有使用創建臨時表,我不能調用proc裏面的存儲過程..現在併發問題導致死鎖,如果我要從派生表連接表而不是調用過程臨時表是一個不同的故事 – flyclassic 2011-04-12 09:27:09