面試命中率90%的點 —— MySQL鎖

1、對MySQL的鎖的瞭解

當數據庫有併發事務的時候,可能會產生數據的不一致,這時候須要一些機制來保證訪問的次序,鎖機制就是這樣的一個機制。算法

就像酒店的房間,若是你們隨意進出,就會出現多人搶奪同一個房間的狀況,而在房間上裝上鎖,申請到鑰匙的人才能夠入住而且將房間鎖起來,其餘人只有等他使用完畢才能夠再次使用。
數據庫

2、隔離級別與鎖的關係

在Read Uncommitted級別下,讀取數據不須要加共享鎖,這樣就不會跟被修改的數據上的排他鎖衝突併發

在Read Committed級別下,讀操做須要加共享鎖,可是在語句執行完之後釋放共享鎖。分佈式

在Repeatable Read級別下,讀操做須要加共享鎖,可是在事務提交以前並不釋放共享鎖,也就是必須等待事務執行完畢之後才釋放共享鎖。ide

SERIALIZABLE 是限制性最強的隔離級別,由於該級別鎖定整個範圍的鍵,並一直持有鎖,直到事務完成。
性能

3、按照鎖的粒度分數據庫鎖有哪些?鎖機制與InnoDB鎖算法

在關係型數據庫中,能夠按照鎖的粒度把數據庫鎖分爲行級鎖(INNODB引擎)、表級鎖(MYISAM引擎)和頁級鎖(BDB引擎 )。spa

  • MyISAM和InnoDB存儲引擎使用的鎖:設計

MyISAM採用表級鎖(table-level locking)。orm

InnoDB支持行級鎖(row-level locking)和表級鎖,默認爲行級鎖。索引

  • 行級鎖,表級鎖和頁級鎖對比

行級鎖:MySQL中鎖定粒度最細的一種鎖,表示只針對當前操做的行進行加鎖。行級鎖能大大減小數據庫操做的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分爲共享鎖和排他鎖。

特色:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。

表級鎖:MySQL中鎖定粒度最大的一種鎖,表示對當前操做的整張表加鎖,它實現簡單,資源消耗較少,被大部分MySQL引擎支持。最常使用的MyISAM與InnoDB都支持表級鎖定。表級鎖定分爲表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。

特色:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖衝突的機率最高,併發度最低。

頁級鎖:是MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。因此取了折衷的頁級,一次鎖定相鄰的一組記錄。

特色:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度通常

4、從鎖的類別上分MySQL都有哪些鎖呢?像上面那樣子進行鎖定豈不是有點阻礙併發效率了

從鎖的類別上來說,有共享鎖和排他鎖。

共享鎖: 又叫作讀鎖。當用戶要進行數據的讀取時,對數據加上共享鎖。共享鎖能夠同時加上多個。

排他鎖: 又叫作寫鎖,當用戶要進行數據的寫入時,對數據加上排他鎖。排他鎖只能夠加一個,他和其餘的排他鎖,共享鎖都相斥。

用上面的例子來講就是用戶的行爲有兩種,一種是來看房,多個用戶一塊兒看房是能夠接受的。一種是真正的入住一晚,在這期間,不管是想入住的仍是想看房的都不能夠。

鎖的粒度取決於具體的存儲引擎,InnoDB實現了行級鎖,頁級鎖,表級鎖。

他們的加鎖開銷從大到小,併發能力也是從大到小。

5、MySQL中InnoDB引擎的行鎖是怎麼實現的?

InnoDB是基於索引來完成行鎖

例: select * from tab_with_index where id = 1 for update;

for update 能夠根據條件來完成行鎖鎖定,而且 ID 是有索引鍵的列,若是 ID不是索引鍵那麼InnoDB將完成表鎖,併發將無從談起

6、InnoDB存儲引擎的鎖的算法有三種

1.Record lock:單個行記錄上的鎖

2.Gap lock:間隙鎖,鎖定一個範圍,不包括記錄自己

3.Next-key lock:record+gap 鎖定一個範圍,包含記錄自己

7、相關知識點:

Innodb對於行的查詢使用next-key lock

Next-locking keying爲了解決Phantom Problem幻讀問題

當查詢的索引含有惟一屬性時,將next-key lock降級爲record key

Gap鎖設計的目的是爲了阻止多個事務將記錄插入到同一範圍內,而這會致使幻讀問題的產生

有兩種方式顯式關閉gap鎖:(除了外鍵約束和惟一性檢查外,其他狀況僅使用record lock)

A. 將事務隔離級別設置爲RC

B. 將參數innodb_locks_unsafe_for_binlog設置爲1

8、什麼是死鎖?怎麼解決?

死鎖是指兩個或多個事務在同一資源上相互佔用,並請求鎖定對方的資源,從而致使惡性循環的現象。

常見的解決死鎖的方法

一、若是不一樣程序會併發存取多個表,儘可能約定以相同的順序訪問表,能夠大大下降死鎖機會。

二、在同一個事務中,儘量作到一次鎖定所須要的全部資源,減小死鎖產生機率;

三、對於很是容易產生死鎖的業務部分,能夠嘗試使用升級鎖定顆粒度,經過表級鎖定來減小死鎖產生的機率;

若是業務處理很差能夠用分佈式事務鎖或者使用樂觀鎖

9、數據庫的樂觀鎖和悲觀鎖是什麼?怎麼實現的?

數據庫管理系統(DBMS)中的併發控制的任務是確保在多個事務同時存取數據庫中同一數據時不破壞事務的隔離性和統一性以及數據庫的統一性。樂觀併發控制(樂觀鎖)和悲觀併發控制(悲觀鎖)是併發控制主要採用的技術手段。

悲觀鎖:假定會發生併發衝突,屏蔽一切可能違反數據完整性的操做。在查詢完數據的時候就把事務鎖起來,直到提交事務。

實現方式:使用數據庫中的鎖機制

樂觀鎖:假設不會發生併發衝突,只在提交操做時檢查是否違反數據完整性。在修改數據的時候把事務鎖起來,經過Version的方式來進行鎖定。

實現方式:通常會使用版本號機制或CAS算法實現。

兩種鎖的使用場景

從上面對兩種鎖的介紹,咱們知道兩種鎖各有優缺點,不可認爲一種好於另外一種,像樂觀鎖適用於寫比較少的狀況下(多讀場景),即衝突真的不多發生的時候,這樣能夠省去了鎖的開銷,加大了系統的整個吞吐量。

但若是是多寫的狀況,通常會常常產生衝突,這就會致使上層應用會不斷的進行Retry,這樣反卻是下降了性能,因此通常多寫的場景下用悲觀鎖就比較合適。

最後

感謝你們看到這裏,文章有不足,歡迎你們指出;若是你以爲寫得不錯,那就給我一個贊吧。

相關文章
相關標籤/搜索