當 web 日志中出現(xiàn)行鎖超時錯誤后,很多開發(fā)都會找我來排查問題,這里說下問題定位的難點!
目前成都創(chuàng)新互聯(lián)公司已為上1000+的企業(yè)提供了網站建設、域名、虛擬主機、網站托管運營、企業(yè)網站設計、汕頭網站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
1. MySQL 本身不會主動記錄行鎖等待的相關信息,所以無法有效的進行事后分析。
2. 鎖爭用原因有多種,很難在事后判斷到底是哪一類問題場景,尤其是事后無法復現(xiàn)問題的時候。
3. 找到問題 SQL 后,開發(fā)無法有效從代碼中挖掘出完整的事務,這也和公司框架-產品-項目的架構有關,需要靠 DBA 事后采集完整的事務 SQL 才可以進行分析。
InnoDB默認是行級別的鎖,當有明確指定的主鍵時候,是行級鎖。否則是表級別。
例子: 假設表foods ,存在有id跟name、status三個字段,id是主鍵,status有索引。
例1: (明確指定主鍵,并且有此記錄,行級鎖)
例2: (明確指定主鍵/索引,若查無此記錄,無鎖)
例3: (無主鍵/索引,表級鎖)
例4: (主鍵/索引不明確,表級鎖)
for update的注意點
for update的疑問點
for update 的作用是在查詢的時候為行加上排它鎖,當一個事務的操作未完成時候,其他事務可以讀取但是不能寫入或更新。
它的典型使用場景是 高并發(fā)并且對于數(shù)據(jù)的準確性有很高要求 ,比如金錢、庫存等,一般這種操作都是很長一串并且開啟事務的,假如現(xiàn)在要對庫存進行操作,在剛開始讀的時候是1,然后馬上另外一個進程將庫存更新為0了,但事務還沒結束,會一直用1進行后續(xù)的邏輯,就會有問題,所以需要用for upate 加鎖防止出錯。
行鎖的具體實現(xiàn)算法有三種:record lock、gap lock以及next-key lock。
只在可重復讀或以上隔離級別下的特定操作才會取得 gap lock 或 next-key lock,在 Select、Update 和 Delete 時,除了基于唯一索引的查詢之外,其它索引查詢時都會獲取 gap lock 或 next-key lock,即鎖住其掃描的范圍。主鍵索引也屬于唯一索引,所以主鍵索引是不會使用 gap lock 或 next-key lock
for update 僅適用于InnoDB,并且必須開啟事務,在begin與commit之間才生效。
select 語句默認不獲取任何鎖,所以是可以讀被其它事務持有排它鎖的數(shù)據(jù)的!
InnoDB 既實現(xiàn)了行鎖,也實現(xiàn)了表鎖。
當有明確指定的主鍵/索引時候,是行級鎖,否則是表級鎖
假設表 user,存在有id跟name字段,id是主鍵,有5條數(shù)據(jù)。
明確指定主鍵,并且有此記錄,行級鎖
無主鍵/索引,表級鎖
主鍵/索引不明確,表級鎖
明確指定主鍵/索引,若查無此記錄,無鎖
參考博文: