update死鎖解決方案

問題:

     多個update語句對數據庫做更新操作時,導致數據庫表死鎖。

SQL語句:

語句1:
UPDATE test_table SET col_4_name = '',col_5_name='' WHERE col_1_name = 'xxx' AND col_2_name = 'xxx' AND col_3_name = 'xxx';
語句2:
UPDATE test_table SET col_4_name = '',col_6_name='' WHERE col_1_name = 'xxx' AND col_2_name = 'xxx' AND col_3_name = 'xxx';


死鎖信息如下:

srv_master_thread loops: 2097506 srv_active, 0 srv_shutdown, 7386562 srv_idle
srv_master_thread log flush and writes: 9483563
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 6972941
OS WAIT ARRAY INFO: signal count 10636711
RW-shared spins 0, rounds 15828779, OS waits 5319938
RW-excl spins 0, rounds 55486192, OS waits 447156
RW-sx spins 1788772, rounds 34121454, OS waits 423421
Spin rounds per wait: 15828779.00 RW-shared, 55486192.00 RW-excl, 19.08 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2019-12-24 09:46:49 0x7f30a87f4700
*** (1) TRANSACTION:
TRANSACTION 90336432, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1136, 4 row lock(s)
MySQL thread id 14616700, OS thread handle 139847291823872, query id 1166213705 10.99.95.237 test_db updating
UPDATE test_table SET col_4_name = '',col_5_name='' WHERE col_1_name = 'xxx' AND col_2_name = 'xxx' AND col_3_name = 'xxx'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 730 page no 820 n bits 200 index PRIMARY of table `test_db`.`test_table` trx id 90336432 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 13; compact format; info bits 0
 0: len 4; hex 80000002; asc     ;;
 1: len 1; hex 30; asc 0;;
 2: len 3; hex 8fbe4e; asc   N;;
 3: len 4; hex 800003e9; asc     ;;
 4: len 4; hex 80000001; asc     ;;
 5: len 30; hex 2f686f6d652f66756e642f6e66732f76612f322f5b4143434f554e545f42; asc /home/fund/nfs/va/2/[ACCOUNT_B; (total 60 bytes);
 6: len 6; hex 000002c9141c; asc       ;;
 7: len 7; hex cd0000018f0110; asc        ;;
 8: len 4; hex 80000005; asc     ;;
 9: len 30; hex e69687e4bbb6e78ab6e680815b534a5358582e6462665de69caae590afe7; asc             [SJSXX.dbf]       ; (total 33 bytes);
 10: len 0; hex ; asc ;;
 11: len 6; hex 5dd6432c07a8; asc ] C,  ;;
 12: len 6; hex 5dd6432c07a8; asc ] C,  ;;

*** (2) TRANSACTION:
TRANSACTION 90336428, ACTIVE 0 sec fetching rows, thread declared inside InnoDB 4740
mysql tables in use 1, locked 1
431 lock struct(s), heap size 57552, 40698 row lock(s), undo log entries 1
MySQL thread id 14616699, OS thread handle 139846962071296, query id 1166213608 10.99.95.237 test_db updating
UPDATE test_table SET col_4_name = '',col_5_name='' WHERE col_1_name = 'xxx' AND col_2_name = 'xxx' AND col_3_name = 'xxx'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 730 page no 820 n bits 200 index PRIMARY of table `test_db`.`test_table` trx id 90336428 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;

查找問題步驟:

      1.查詢死鎖信息:

         (1).執行sql:

show engine innodb status;

         (2).查詢結果:如下圖,status中的信息就是死鎖信息,將其內容複製出來分析;

    2.分析上一步中查詢到的死鎖信息,找到產生死鎖的sql語句:

     2.查看執行計劃:

        (2.1).SQl語句:

EXPLAIN UPDATE test_table SET col_4_name = '',col_5_name='' WHERE col_1_name = 'xxx' AND col_2_name = 'xxx' AND col_3_name = 'xxx';

       (2.2).分析執行計劃:type爲range,rows爲若干條數據,需要優化。

解決方案:本質是破壞死鎖產生的必要條件

      此案例解決方案一:加索引,適合於主鍵爲複合主鍵

         1.SQL語句

ALTER TABLE test_table ADD INDEX idx_test_table(col_1_name,col_2_name,col_3_name);

         2.注意點:索引的中的字段順序要與update語句後面的條件一致,可不包含所有條件字段,可視情況而定;

      此案例解決方案二:先select查詢所要更新的語句,然後根據主鍵更新,適合於主鍵爲唯一主鍵

         1.SQL語句

// 查詢
SELECT xxx FROM test_table WHERE col_1_name = 'xxx' AND col_2_name = 'xxx' AND col_3_name = 'xxx';
// 更新對應的記錄
UPDATE test_table SET col_4_name = '',col_5_name='' WHERE XXX ='XXX';


            
原因:

      1.此示例原因:主鍵爲複合主鍵時,主鍵的順序和執行語句後面的條件順序不一致,導致踩了部分索引,使大量數據被鎖定,其他語句執行時,導致死鎖。

      2.官方解釋:1. 互斥條件;2. 請求和保持條件;3. 不剝奪條件;4. 循環等待條件。

 

相關知識點:

      1.數據庫索引相關知識;

      2.數據庫鎖機制,產生的原因,解決方法等;


代碼示例:

     如上。
 

發佈了20 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章