線上數據庫用戶反映數據提交很慢,前端遮罩屏蔽處理一個在轉,因而看了應用的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引擎出現鎖整個表記錄而出現了資源爭用