記一次MySQl Deadlock處理

線上數據庫用戶反映數據提交很慢,前端遮罩屏蔽處理一個在轉,因而看了應用的log日誌文件,出現幾百kb的文件錯誤,仔細看應用在調用一個存儲過程的拋出了前端

Deadlock found when trying to get lock

這個排除了應用的問題,因而着手到數據層面找緣由。mysql

1.檢查數據db引擎的狀態statussql

經過登陸mysql服務器使用使用以下命令將db status重定向輸出到指定的文件分析數據庫

mysql -e "show engine innodb status\G" -u[name] -p[password] [database] > /usr/local/status.txt

查看status.txt文件中的發現果真是存儲過程的問題,文件sql語句讓我很吃驚,什麼鬼怎麼後面會本身使用NAME_CONST而後還把編碼轉成utf8mb4。服務器

ts.user_id =  NAME_CONST('userId',_utf8mb4'5ba51b22' COLLATE 'utf8mb4_general_ci')

而後我把語句拷貝加上explain查看執行計劃,發現走了全表掃描,沒有走user_id索引,若是NAME_CONST中的內容去掉,直接賦值id值,發現執行計劃預估值只有20幾行。應該是很快的。函數

這是開始檢查user_id字段子表中的編碼,發現是utf8並非utf8mb4,經過show variables查看數據庫編碼也是utf8。google

//toggle
mysql> use xxx;
//character_set
mysql>show variables like 'character_set_database';

爲何會出現強制改編碼呢。其實也沒遇到過這樣的問題。也沒有經驗,這個時候不知道咋辦了,只好打開google輸入mysql procedure utf8mb4一篇快速瀏覽沒有發現線索,點了第二編也是快速閱覽,大概是來自stackoverflow,一個show procedure status忽然吸引到我,雖然提問者問題和個人問題並不同。我很好奇編碼

這個命令到底展示啥。而後看到內容大體以下:日誌

個人character_set_client和collation_connection的編碼都是utf8而Database collation的編碼是utf8mb4code

//來自mysql官網
mysql> SHOW PROCEDURE STATUS\G
*************************** 1. row ***************************
                  Db: test
                Name: sp1
                Type: PROCEDURE
             Definer: testuser@localhost
            Modified: 2004-08-03 15:29:37
             Created: 2004-08-03 15:29:37
       Security_type: DEFINER
             Comment:
character_set_client: latin1
collation_connection: latin1_swedish_ci
  Database Collation: latin1_swedish_ci

我忽然想起了以前爲了兼容表情把數據編碼改爲了utf8mb4,可是後來又把數據庫改回了utf8,這時個人腦海裏忽然以爲存儲過程的Database Collation的編碼依賴於建立時數據庫的編碼和當前的編碼無關,因而快速的從新建立一個存儲過程覆蓋原來的存儲過程,再用show procedure status like 'xxx' \G查看,發現編碼已經修改。

結論:在改變數據庫編碼後須要使用show xxx status命令檢查以前建立的表、存儲過程、觸發器、函數的編碼是否與當前一致,不然作相應的編碼修改。對dead lock通常都是因爲數據變動數據時沒有走索引致使innodb引擎出現鎖整個表記錄而出現了資源爭用

相關文章
相關標籤/搜索