天天看點

Mysql鎖--mysql詳解(十二)

上篇文章說了mvcc保證事務隔離性,隔離有髒讀,不可重複讀,幻讀,而mysql有四種隔離級别,read uncommit,read commit,repeatable read,serializable,解決這些問題,mysql新版本預設是可重複讀,利用mvcc解決幻讀,read view連結清單組成有m_ids活躍事務id,最大事務id和最小事務id以及目前事務id,解決的是快照讀,目前讀還是會存在一定問題。

Mysql鎖

首先我們知道讀的時候是不需要加鎖的,當幾個線程同時寫入的時候,操作同一條資料,修改資料的那個事務就會生成鎖。

鎖結構裡有事務id和是否等待is_waiting,正在修改資料的事務則沒有等待,is_Waiting就是false,其他事務需要等這個事務完成後,他們is_Waiting才會從true變為false。

怎麼解決上篇文章說的髒讀,不可重複讀,幻讀呢,讀寫都加鎖,自然都可以解決以上問題,但是這樣很明顯發生阻塞,效率會低,于是可以采用select讀的時候mvcc版本控制,寫的時候再加鎖。這裡說的mvcc版本控制來實作的叫一緻性讀,也就是經常說的快照讀。

鎖定讀:

必須是innodb資料庫,必須開啟事務。

Lock in share mode共享鎖(s鎖):當一個事務查詢後,其他事務可以讀,不可以寫。

For update 排它鎖(x鎖):當一個事務查詢後,其他事務不可以讀也不可以寫。

那麼delete呢:其實就是先在b+樹中定位到這條記錄的位置,然後擷取這條記錄x鎖,在執行delete mark操作。

Update分為三種情況:修改鍵值,則先delete再次insert。未修改鍵值,但是列長度發生變化,也需要delete再次insert,若未修改鍵值,但長度未發生變化,可以看做在b+樹位置直接記錄x鎖。

Insert的情況下并不加鎖,而是通過隐式鎖來保護。

表的顆粒分為行鎖和表鎖,行鎖上的就是s鎖和x鎖,當整個表上鎖的時候,其他事務應該也是不可以通路的,這時候怎麼知道他上了表鎖呢,或者循環他嗎,當然不是,mysql設定了意向鎖,is鎖和ix鎖,當表上了ix鎖的時候,這時候其他事務想上s鎖是不允許的。(其他搜尋引擎因為不支援事務,是以他們的鎖隻存在session中,而且隻支援表鎖,不支援行鎖)

Is鎖和ix鎖就是當後面需要上表鎖的時候,需要判斷是否有行鎖,因為is鎖和ix鎖是在上了行的s鎖和x鎖之前加的。