原文:Mycat事務超時
問題
項目里面使用的是mycat進行分庫分表,但在最近一個系統更新后出現數據庫事務鎖超時的問題,如下面的錯誤:
Caused by: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
分析
先在網上搜索了一下之后,發現大多數說的都不是什么好的解決方案,手動kill掉事務,把事務超時時間加長,這些對我現在這個項目都不實際,還是自己分析吧。
對數據庫的配置檢查了一番,沒什么問題,並沒有什么更新,然后就對程序進行分析,這個錯誤是在一次系統更新后才出現的,對這次更新進行了分析,發現頻繁超時的那個更新操作去掉了一個分片id參數,比如之前是這樣:
update update_date = now() where xxx_id = 123 and sharding_id = 23;
這次更新后的操作就是這樣子了:
update update_date = now() where xxx_id = 123;
分析了一下這個操作,xxx_id
只是一個普通的字段,然而這個操作會鎖住所有分片下的表,而加了分片id之后只是鎖住了指定分片的那張表。我們使用的是MySQL innoDB引擎,所以,把這個操作變成行鎖就好了。
解決方案
MySQL innoDB引擎行鎖是建立在索引上的,所以給xxx_id
這個字段加上索引就好了。關於行鎖請參考:MySQL innoDB引擎鎖機制。
加上索引后在mycat里無論加不加上分片id都能夠避免鎖表了。
其他
為什么會去掉分片id?
那張表分表時分片id用錯了(后來發現的),新業務上線修正后會導致數據獲取不到,所以暫時去掉分片id,后面修復。
mysql & mycat
對mysql索引又有一個新的理解吧,至於給mysql加上索引后mycat怎樣找到分片還是不太清楚,還是要繼續學習。