mysql行級鎖是怎么工作的?
加鎖的對象是索引,加鎖的基本單位是 next-key lock。在能使用記錄鎖或者間隙鎖就能避免幻讀現象的場景下, next-key lock 就會退化成記錄鎖或間隙鎖。
鎖的范圍,總結一下就是,對于唯一索引,鎖只有對應的記錄或者所在范圍即可;非唯一索引則要看看可能加上一個范圍,因為即使找到了索引也是非唯一的。
這個比較復雜,請移步這篇博客以及這篇博客
假設鎖定讀查詢用到索引,就會鎖住二級索引對應位置和查詢到的記錄的主鍵索引(沒查到就不用鎖主鍵索引)。如果鎖定讀查詢語句,沒有使用索引列作為查詢條件,或者查詢語句沒有走索引查詢,導致掃描是全表掃描。那么,每一條記錄的索引上都會加 next-key 鎖,這樣就相當于鎖住的全表,這時如果其他事務對該表進行增、刪、改操作的時候,都會被阻塞。
不只是鎖定讀查詢語句不加索引才會導致這種情況,update 和 delete 語句如果查詢條件不加索引,那么由于掃描的方式是全表掃描,于是就會對每一條記錄的索引上都會加 next-key 鎖,這樣就相當于鎖住的全表。
因此,在線上在執行 update、delete、select … for update 等具有加鎖性質的語句,一定要檢查語句是否走了索引,如果是全表掃描的話,會對每一個索引加 next-key 鎖,相當于把整個表鎖住了,這是挺嚴重的問題。