一個項目中mysql數據庫經常死鎖的問題解決記錄


1、問題描述

此項目為一個物流系統,需要使用PDA對貨物進行入庫、備貨、出貨等操作,在系統開發測試過程中,經常發現死鎖問題。

有這樣一種業務場景:倉庫對備貨單上貨進行掃碼備貨后,點擊”完成”以確定完成了該備貨單,才能進行下一步的發車動作,也即是說,如果不對單進行”完成”動作,就無法進行發車。倉庫使用人員經常反饋已經點擊了完成,但是不生效。此問題很詭異,有時很正常,有時頻繁發生,聯系開發人員檢查代碼,檢查網絡,很久都沒有解決,很是頭疼。倉庫使用較大意見,項目推進遇到很大阻力。

最后經過摸索,問題得到解決。因為問題重現比較難,自己測試的時候都無問題(還懷疑過使用人員是否誤報),此問題的解決剛開始要等出現的時候觀察,慢慢有點頭緒,再通過腳本方式進行巡檢,再分析,最終才得到解決。解決方法記錄如下

2、問題分析過程

2.1、編寫事務監控與鎖沖突監控腳本

普及下如下三個表的作用

innodb_trx ## 當前運行的所有事務
innodb_locks ## 當前出現的鎖
innodb_lock_waits ## 鎖等待的對應關系

在出現問題的時候,通過觀察innodb_trx發現,經常有一些事務執行很久,一直在執行,也不會關閉,同時觀察innodb_locks表,會出現死鎖現象

於是寫了兩個腳本分別對innodb_trx、innodb_locks表進行監控,腳本1每5秒鍾記錄innodb_trx的情況,腳本2每1分鍾監控innodb_locks的情況,如果innodb_locks有數據代表有出現死鎖

腳本1監控使用如下命令:此命令查詢正在執行的事務,需要說明的是有事務不一定是有死鎖,只是代表有一個事務在執行還未commit,本腳本不發告警郵件,只做記錄

1 SELECT * FROM information_schema.INNODB_TRX\G;

image

腳本2監控使用如下命令:如果有鎖沖突,此表會有數據,如果未鎖表,此表為空。此腳本發現有死鎖就發郵件通知,以便問題的及時核查

1 SELECT * FROM information_schema.INNODB_locks;

image

2.2、開啟mysql的general日志

開啟general log會將所有到達MySQL Server的SQL語句記錄下來。一般不會開啟此功能,因為log的量會非常龐大。
但個別情況下可能會臨時的開一會兒general log以供排障使用。

相關參數一共有3:general_log、log_output、general_log_file

  • general_log:全局動態變量,默認關閉
  • log_output :全局動態變量,可取FILE、TABLE、NONE。其中TABLE存儲方式比較方便按條件檢索。若指定為NONE,則即使general_log開啟了也不會記錄log。若log_output指定為TABLE,則會在mysql數據庫下邊創建一個general_log表。需要注意的是該參數不僅僅影響general的存儲方式還影響slow的存儲方式,這一點需要特別注意。
  • general_log_file:全局動態變量,日志文件名,不指定的話默認為hostname.log,位於數據目錄下。

開啟命令:

  1 set global general_log=on

注:此命令是臨時開啟,如果mysql重啟后回默認關閉

關閉命令:

  1 set global general_log=off


2.3、核查分析

在出現死鎖的時候,分別對general日志與腳本記錄的innodb_trx數據進行分析,如下:

image

查看監控innodb_trx的日志情況,兩個時間對了下(如上下圖時間),確定了就是beihuovr存儲過程執行才出現的這個一直執行的事務

clip_image001[8]

分析:

同一個會話分別執行beihu和beihuovr存儲過程出現問題,單獨執行beihuovr沒有問題,進一步分析beihu和beihuovr存儲過程的內容

  • beihuovr存儲過程沒有設置autocommit=0,既會自動提交
  • beihu存儲過程設置了autocommit=0,關閉了自動提交

按道理beihuovr這個存儲過程的事務不會一直執行才對,那么就有一種可能,因為是同一個線程執行兩個存儲過程,可能是beihuovr存儲過程繼承了beihu存儲過程的autocommit屬性,存儲過程里面也沒有commit操作,導致這個存儲過程的事務一直在執行。

3、解決辦法

在每個存儲過程的開始設置autocommit=1,問題解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM