MySQL之入門必備知識總結

我的學習MySQL的總結學習筆記,參考資料都在文末給出,建議閱讀

1、讀寫鎖

  • 互斥鎖(Exclusive),簡寫爲 X 鎖,又稱寫鎖。
  • 共享鎖(Shared),簡寫爲 S 鎖,又稱讀鎖。

有如下兩個規定:html

  • 一個事務對數據對象 A 加了 X 鎖,就能夠對 A 進行讀取和更新。加鎖期間其它事務不能對 A 加任何鎖。
  • 一個事務對數據對象 A 加了 S 鎖,能夠對 A 進行讀取操做,可是不能進行更新操做。加鎖期間其它事務能對 A 加 S 鎖,可是不能加 X 鎖。

鎖的兼容關係以下:git

在這裏插入圖片描述

2、鎖粒度

一種提升共享資源併發性的方式就是讓鎖定對象更具備選擇性。github

應該儘可能只鎖定須要修改的那部分數據,而不是全部的資源。在給定的資源上,鎖定的數據量越少,發生鎖爭用的可能性就越小,於是能夠提升系統的併發程度。sql

可是加鎖須要消耗資源,鎖的各類操做(包括得到鎖、釋放鎖、檢查鎖是否已經解除)都會增長系統開銷。所以封鎖粒度越小,系統開銷就越大。數據庫

所謂的鎖策略,就是在鎖的開銷和數據的安全性之間尋求平衡。MySQL 中提供了兩種封鎖粒度:行級鎖以及表級鎖。安全

通常都是在表上施加行級鎖,並以各類複雜的方式來實現,以便鎖在比較多的狀況下儘量地提供更好的性能。服務器

每種MySQL存儲引擎均可以實現本身的鎖策略和鎖粒度,因此能夠根據應用場景選擇不一樣的方案。併發

表鎖

鎖定整張表,是MySQL中最基本的鎖策略,而且是開銷最小的策略。性能

READ_LOCAL表鎖支持某些類型的併發操做。在表鎖中,寫鎖比讀鎖具備更高的優先級,所以寫鎖能夠插入到鎖隊列中讀鎖的前面,反之則不能。學習

MySQL服務器會爲諸如ALTER_TABLE之類的語句使用表鎖,而忽略存儲引擎的鎖機制。

行鎖

最大程度地支持併發處理,同時帶來了最大的鎖開銷。

行級鎖只在存儲引擎層面實現,MySQL服務器層徹底不瞭解存儲引擎的鎖實現。

3、事務

概念

在這裏插入圖片描述

事務指的是知足 ACID 特性的一組操做,事務內的語句要麼所有執行成功,要麼所有執行失敗,能夠經過 Commit 提交一個事務,也可使用 Rollback 進行回滾。

可使用START TRANSACTION顯式地開啓一個事務,而後使用COMMIT提交事務將修改的數據持久保留,或者使用ROOLBACK撤銷全部的修改(回滾)。

MySQL 默認採用自動提交模式。也就是說,若是不顯式START TRANSACTION使用語句來開始一個事務,那麼每一個查詢操做都會被當作一個事務並自動提交。

ACID

原子性(Atomicity)

一個事務被視爲一個不可分割的最小工做單元,整個事務中的全部操做要麼所有提交成功,要麼所有失敗回滾。

回滾能夠用回滾日誌(Undo Log)來實現,回滾日誌記錄着事務所執行的修改操做,在回滾時反向執行這些修改操做便可。

一致性(Consistency)

數據庫老是從一個一致性狀態轉換到另外一個一致性狀態。事務若是最終沒有提交,那麼事務的修改也不會保存到數據庫中。在一致性狀態下,全部事務對同一個數據的讀取結果都是相同的。

隔離性(Isolation)

一個事務所作的修改在最終提交之前,對其它事務是不可見的。

持久性(durability)

一旦事務提交,則其所作的修改將會永遠保存到數據庫中。即便系統發生崩潰,事務執行的結果也不能丟失。持久性策略有多種級別,但不可能作到100%的持久性保證。

系統發生奔潰能夠用重作日誌(Redo Log)進行恢復,從而實現持久性。與回滾日誌記錄數據的邏輯修改不一樣,重作日誌記錄的是數據頁的物理修改。

事務的 ACID 特性概念簡單,但不是很好理解,主要是由於這幾個特性不是一種平級關係:

  • 只有知足一致性,事務的執行結果纔是正確的。
  • 在無併發的狀況下,事務串行執行,隔離性必定可以知足。此時只要能知足原子性,就必定能知足一致性。
  • 在併發的狀況下,多個事務並行執行,事務不只要知足原子性,還須要知足隔離性,才能知足一致性。
  • 事務知足持久化是爲了能應對系統崩潰的狀況。

在這裏插入圖片描述

對於一些不須要事務的查詢類應用,選擇一個非事務型的存儲引擎(如MyISAM),能夠得到更高的性能。即便存儲引擎不支持事務,也能夠經過使用LOCK TABLES爲應用提供保護。

4、隔離級別

未提交讀(READ UNCOMMITTED)

事務中的修改即便沒有提交,對其餘事務也都是可見的,事務能夠讀取未提交的數據,叫作髒讀。

未提交讀的性能不會比其餘級別好太多,但卻缺少其餘級別的不少優勢,在實際應用中不多使用。

提交讀(READ COMMITTED)

大多數據庫系統的默認隔離級別都是提交讀,但MySQL不是。也可叫作不可重複度級別,由於執行兩次相同的查詢,可能會獲得不同的結果。

一個事務開始時,只能讀取到已經被提交的修改。換句話說,一個事務所作的修改在提交以前對其它事務是不可見的。

可重複讀(REPEATABLE READ)

可重複讀是MySQL的默認事務隔離級別。

解決了未提交讀級別中的髒讀問題。該級別保證在同一個事務中屢次讀取同一數據的結果是同樣的。

可重複讀沒法解決幻讀問題。所謂幻讀,指的是,T1 讀取某個範圍的數據,T2 在這個範圍內插入新的數據,T1 再次讀取這個範圍的數據,此時讀取的結果和和第一次讀取的結果不一樣。

可串行化(SERIALIZABLE)

經過強制事務串行執行,在讀取的每一行數據上都加鎖,解決了幻讀的問題,可是可能會致使超時和鎖爭用問題。

產生併發不一致性問題的主要緣由是破壞了事務的隔離性,解決方法是經過併發控制來保證隔離性。併發控制能夠經過封鎖來實現,可是封鎖操做須要用戶本身控制,至關複雜。數據庫管理系統提供了事務的隔離級別,讓用戶以一種更輕鬆的方式處理併發一致性問題。

5、封鎖協議

1. 三級封鎖協議

一級封鎖協議

事務 T 要修改數據 A 時必須加 X 鎖,直到 T 結束才釋放鎖。

能夠解決丟失修改問題,由於不能同時有兩個事務對同一個數據進行修改,那麼事務的修改就不會被覆蓋。

在這裏插入圖片描述

二級封鎖協議

在一級的基礎上,要求讀取數據 A 時必須加 S 鎖,讀取完立刻釋放 S 鎖。

能夠解決讀髒數據問題,由於若是一個事務在對數據 A 進行修改,根據 1 級封鎖協議,會加 X 鎖,那麼就不能再加 S 鎖了,也就是不會讀入數據。

在這裏插入圖片描述

三級封鎖協議

在二級的基礎上,要求讀取數據 A 時必須加 S 鎖,直到事務結束了才能釋放 S 鎖。

能夠解決不可重複讀的問題,由於讀 A 時,其它事務不能對 A 加 X 鎖,從而避免了在讀的期間數據發生改變。

在這裏插入圖片描述

2. 隱式鎖定與顯示鎖定

隱式鎖定

InnoDB採用兩階段鎖定協議,也叫兩段鎖協議。

在事務執行過程當中,隨時均可以執行鎖定,鎖只有在執行提交或者回滾時纔會同時釋放。InnoDB會根據隔離級別在須要的時候自動加鎖

顯示鎖定

* SELECT ... LOCK IN SHARE MODE
* SELECT ... FOR UPDATE

MySQL也能夠在服務器層面實現 LOCK TABLES 和 UNLOCK TABLES。

3. 兩段鎖協議

加鎖階段

在該階段能夠進行加鎖操做。在對任何數據進行讀操做以前要申請並得到共享鎖鎖,在進行寫操做以前要申請並得到排他鎖。加鎖不成功,則事務進入等待狀態,直到加鎖成功才繼續執行。

解鎖階段

當事務釋放了一個封鎖之後,事務進入解鎖階段,在該階段只能進行解鎖操做不能再進行加鎖操做。

6、多版本併發控制

多版本併發控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存儲引擎實現隔離級別的一種具體方式,用於實現提交讀和可重複讀這兩種隔離級別。而未提交讀隔離級別老是讀取最新的數據行,要求很低,無需使用 MVCC。可串行化隔離級別須要對全部讀取的行都加鎖,單純使用 MVCC 沒法實現。

實現原理

MVCC是經過保存數據在某個時間點的快照來實現的,不一樣的存儲引擎的MVCC實現是不一樣的,典型的有樂觀併發控制和悲觀併發控制。

InnoDB的MVCC經過在每行記錄後面保存兩個隱藏的列來實現。一個列保存建立時的系統版本號,一個列保存行的過時時(刪除時間)的系統版本號。

每開始一個新的事務,系統版本號都會自動遞增。事務開始時刻系統的版本號會做爲事務的版本號,用來和查詢到的每行記錄的版本號進行比較。

具體實現

SELECT

InnoDB會根據兩個條件檢查每行記錄,只有符合如下兩個條件的記錄纔會被做爲結果返回

  1. 只查找行的系統版本號小於或等於事務的系統版本號。可確保讀取到的記錄要麼在本事務以前已存在,要麼是本事務進行的修改。
  2. 行的版本號要麼未定義,要麼大於當前事務的版本號。能夠確保事務讀取的行在事務開始以前未被刪除。

INSERT

InnoDB爲新插入的每一行保存當前系統版本號做爲行版本號。

DELETE

InnoDB爲刪除的每一行保存當前系統版本號做爲刪除標識。

UPDATE

InnoDB新插入一條紀錄,保存當前系統版本號爲行版本號,同時保存當前系統版本號到原來的行做爲行刪除標識。

優缺點

使用系統版本號,在大多數狀況下的讀操做均可以不用加鎖,使得讀數據變得更簡單,提供系統性能,而且保證讀取到的記錄符合標準。

可是每一行都須要額外使用存儲空間,且須要作更多的檢查以及維護。


參考資料

《高性能MySQL》
cyc2018
美團技術團隊——InnoDB中的事務隔離級別和鎖的關係
相關文章
相關標籤/搜索