MySQL InnoDB引擎鎖的總結

2022-07-13 01:33:11 字數 2764 閱讀 8162

我們開的的各式各樣系統中,系統執行需要cpu、記憶體、i/o、磁碟等等資源。但除了硬資源外,還有最為重要的軟資源:資料

當人們訪問操作我們的系統時,其實歸根是對資料的檢視與生產。那麼對於同乙份資料,如果多個使用者同時對它檢視、修改時會出現什麼問題呢?這必然會帶來競爭,而為了控制併發的讀取、修改資料會對資料造成的不一致、錯亂等問題,資料庫引入了鎖的機制。

當然鎖的問題解決了併發訪問資料的問題,而不可避免的會對系統的效能產生負面影響。總結一下各種鎖的使用場景方便在實踐中更好的運用它從而提公升系統效能。

我們日常開發中用到最多的儲存引擎是innodb 與 myisam兩種,而 innodb 現在更多是首選,因此主要是對 innodb 的說明,myisam 跟多是作為乙個對比的角色。

mysql的鎖可以按照多種方式進行劃分,這裡使用最常用的兩種方式進行劃分:粒度與使用方式。

需要特別說明的是:樂觀鎖與悲觀鎖並不是資料庫中實現的鎖機制,是需要我們自己去實現的。它是一種思想,我們不僅僅可以用在mysql中,其它地方有需要的也可以用到。而像悲觀鎖它也是利用資料庫現有的機制進行實現的。下面先根據不同分類對說明相關概念。

樂觀鎖機制採取了更加寬鬆的加鎖機制。悲觀鎖大多數情況下依靠資料庫的鎖機制實現,以保證操作最大程度的獨占性。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。相對悲觀鎖而言,樂觀鎖更傾向於開發運用。

悲觀鎖具有強烈的獨佔和排他特性。它指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改資料)。

表級鎖是mysql中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分mysql引擎支援。最常使用的myisam與innodb都支援表級鎖定。表級鎖分為表共享讀鎖與表獨佔寫鎖。

行級鎖是mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖 和 排他鎖。

頁級鎖是mysql中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以取了折中的頁級,一次鎖定相鄰的一組記錄。bdb支援頁級鎖。

這裡需要說明的是,悲觀鎖是一種思想,它的實現是使用了 共享鎖與排他鎖來實現的。因此悲觀鎖本身並不是mysql實現的鎖機制,它是我們造出來的乙個概念。

innodb 實現了兩種型別的行鎖,共享鎖(s)與排他鎖(x)。然後由於 innodb引擎又支援表級鎖,所以它內部又有意向共享鎖(is)與意向排他鎖(ix)。這兩種表鎖,都是innodb內部自動處理,換句話說我們寫**是無法控制也不需要控制的。我們能控制的是s與x鎖。

在日常操作中,updateinsertdeleteinnodb會自動給涉及的資料集加排他鎖,一般的select一般是不加任何鎖的。我們可以使用以下方式顯式的為select加鎖。

共享鎖:select * form table where id = 10 lock in share mode

排他鎖:select * from table where id = 10 for update

那麼什麼時候該用共享鎖什麼時候用排他鎖呢?

一般來講,共享鎖主要用在需要資料依存關係時來確認某行記錄是否存在,並確保沒有人對這個記錄進行update或者delete操作(包括加鎖的事物也只能讀)。簡單說就是大家都可以讀資料,但是無法修改(更新或者刪除),因此我認為共享鎖也是悲觀鎖的一種實現。

排他鎖是與共享鎖相對應,自身加排他鎖的事物能夠自己發起修改操作,其它事物無法再對該資料加共享或者排他鎖。

這裡需要注意上面說到的一點,由於innodb引擎是行鎖,不管我們在這條資料上加了共享鎖還是排他鎖,簡單的select語句依然可以使用的,因為預設在innodb中select是不加鎖的。

這裡還有一點,上圖中我們寫到乙個間隙鎖,這是什麼東西?比如:當我們用範圍條件而不是相等條件檢索資料,並請求共享或排他鎖時,innodb會給符合條件的已有資料的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫做「間隙(gap)」,innodb也會對這個「間隙」加鎖,這種鎖機制就是所謂的間隙鎖(next-key鎖)。它存在的主要目的有乙個是為了解決幻讀問題,因為rr作為innodb的預設事物隔離級別,是存在幻讀問題的,而我們在實際操作中確沒有出現,就是因為這裡做了處理。

關於樂觀鎖是如何加鎖的,這個不同系統有不同的實現,簡單來說,對每乙個資料維護乙個版本號,每次讀取時把版本號讀取出來,更新時版本號+1。然後更新時將讀取的版本號作為條件,如果有其它事物更新了,那麼必然會導致版本號變化,因為本次更新不會成功。這種機制最大程度的保證了併發。

innodb行鎖是通過索引上的索引項來實現的,這一點mysql與oracle不同,後者是通過在資料中對相應資料行加鎖來實現的。innodb這種行鎖實現特點意味者:只有通過索引條件檢索資料,innodb才會使用行級鎖,否則,innodb將使用表鎖!

在實際應用中,要特別注意innodb行鎖的這一特性,不然的話,可能導致大量的鎖衝突,從而影響併發效能

Mysql innodb引擎(二)鎖

專案 isixsx is相容 相容相容 不相容ix 相容相容 不相容不相容s相容 不相容相容 不相容x 不相容不相容 不相容不相容 是指 innodb 通過多版本控制的方式來讀取當前執行時間資料庫中的資料。如果,讀取的時候行正好在執行 delete 或 update 的排他操作,那讀取操作不會等待,...

MYSQL InnoDB儲存引擎 鎖

目錄 鎖的型別 行級鎖 意向鎖 一種表級鎖 一致性非鎖定讀 innodb儲存引擎的預設設定 行鎖的3種演算法 死鎖 innodb儲存引擎實現了如下兩種標準的行級鎖 1 共享鎖 s lock 允許事務讀一行資料。select column from table lock in share mode 2...

MySQL Innodb引擎鎖總結

1.鎖的目的是什麼?innodb中利用mvcc 多版本併發控制 可以在不加鎖的情況下提高併發訪問下系統的吞吐量。但有些場景下併發訪問必須要在鎖的保護下進行,比如併發的更新。2.鎖的分類 一般鎖是指lock。innodb中還有不常用的一種輕量級鎖latch,latch中不存在死鎖檢測機制,適合加鎖時間...