Mysql-各種鎖區分與MVCC的詳解

mysql的鎖貌似有很多啊,查了大部分資料,

什么表鎖,行鎖,頁鎖

共享鎖,排他鎖,意向鎖,讀鎖,寫鎖

悲觀鎖,樂觀鎖。。

我去,真想問一句,有沒有 金鎖?我還范冰冰呢。。。

哎呀怎么感覺好亂啊。那么把它好好整理總結下吧。

后邊還有對在innodb下的mvcc理解與舉例,在并發量的訪問下如何保持高效一致?簡單易懂了解下,聽朋友說大公司面試也愛問這個。

表/行/頁-鎖:

表級鎖(table-level locking):MyISAM和MEMORY存儲引擎

行級鎖(row-level locking) :InnoDB存儲引擎

頁面鎖(page-level-locking):BDB存儲引擎

表級鎖:開銷小,并發低,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,并發度也最低

行級鎖:開銷大,并發高,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,并發度也最高。

頁面鎖:開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖;鎖定粒度界于表鎖和行鎖之間,并發度一般。

共享/排他鎖

共享鎖又稱讀鎖,是讀取操作創建的鎖。其他用戶可以并發讀取數據,但任何事務都不能對數據進行修改(獲取數據上的排他鎖),直到已釋放所有共享鎖。

排他鎖又稱寫鎖,如果事務T對數據A加上排他鎖后,則其他事務不能再對A加任任何類型的封鎖。獲準排他鎖的事務既能讀數據,又能修改數據。

Mysiam鎖模式

MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作(UPDATE、delete、INSERT等)前,會自動給涉及的表加寫鎖。

a、對MyISAM表的讀操作(加讀鎖),不會阻塞其他進程對同一表的讀請求,但會阻塞對同一表的寫請求.只有當讀鎖釋放后才會執行其它進程的寫操作。

b、對MyISAM表的寫操作(加寫鎖),會阻塞其他進程對同一表的讀和寫操作,只有當寫鎖釋放后,才會執行其它進程的讀寫操作。

innodb鎖模式

意向鎖是InnoDB自動加的,不需要用戶干預。

對于insert、update、delete,InnoDB會自動給涉及的數據加排他鎖(X);對于一般的Select語句,InnoDB不會加任何鎖,事務可以通過以下語句給顯示加共享鎖或排他鎖。

共享鎖:?SELECT … LOCK IN SHARE MODE;

排他鎖:?SELECT … FOR UPDATE;

MVCC(Multiversion?concurrency?control)

一個很難懂得概念,查閱了很多資料與博客,下邊做一個簡單易懂的理解。

情景模擬:

在高并發的前提下,一定要注意這個前提。

事務L1修改某表中D的key值,還未提交;

事務L2同樣也修改D的key值,提交;然后L1提交。

發生了什么?

L1從D讀取key:123對應的值100

L2從D讀取key:123對應的100

L1對值增加1,將key:123更新為100 + 1

L2對值增加2,將key:123更新為100 + 2

如果L1和L2串行執行,key:123對應的值將為103,但上面并發執行中L1的執行效果完全被L2所覆蓋,實際key:123所對應的值變成了102。就因為L1事務沒提交呢,L2又來了。

那如何處理呢?

方法一:

加鎖唄。前邊不都是在說這個鎖的問題呢,把他加寫鎖,等L1執行完再執行L2??梢允强梢裕前l生了排隊,并發下降了。這是一種悲觀一般把基于鎖的并發控制機稱成為悲觀機制。

方法二:

為了實現可串行化,同時避免鎖機制存在的各種問題,我們可以采用基于多版本并發控制(Multiversion?concurrency?control,MVCC)思想的無鎖并發機制,終于把要說的引出來了!人們一般把基于鎖的并發控制機稱成為悲觀機制(悲觀鎖),而把MVCC等機制稱為樂觀機制(樂觀鎖)。加入版本號的一個機制,由D維護該版本號,每次數據有更新就增加版本號,通過版本號來更加高效的管理事務一致性與高并發的問題。

因為鎖機制是一種預防性的,讀會阻塞寫,寫也會阻塞讀,當鎖定粒度較大,時間較長是并發性能就不會太好;而MVCC是一種后驗性的,讀不阻塞寫,寫也不阻塞讀,等到提交的時候才檢驗是否有沖突,由于沒有鎖,所以讀寫不會相互阻塞,從而大大提升了并發性能。

?以上就是mysql-各種鎖區分與mvcc的詳解的內容,更多相關內容請關注php中文網(www.php.cn)!

? 版權聲明
THE END
喜歡就支持一下吧
點贊11 分享