MySQL 筆記 - 事務&鎖

寫在前面

這是一篇讀(重)書(點)筆(摘)記(要)~內容爲《高性能 MySQL》第一章~sql

and 七夕快樂,因此今天的配圖是粉紅色的(๑•̀ㅂ•́)و✧數據庫

事務

簡單的說,事務就是一組原子性的 SQL 查詢,這一組 SQL 要麼所有執行成功,要麼所有執行失敗。這裏簡單介紹一下事務的 ACID,ACID 表示原子性、一致性、隔離性和持久性。markdown

  • 原子性:一個事務是不可分割的最小工做單元,整個事務要麼所有成功,要麼所有失敗,不可能只執行中間的一部分操做。
  • 一致性:執行事務是使得數據庫從一個一致性狀態到另外一個一致性狀態,若是事務最終沒有被提交,那麼事務所作的修改也不會保存到數據庫中。
  • 隔離性:一般來講,一個事務提交以前對其餘事務是不可見的,可是這裏所說的不可見須要考慮隔離級別,好比未提交讀在提交前對於其餘事務來講也是可見的,隔離級別,在下面會詳細講。
  • 持久性:事務一旦被提交,那麼對數據庫的修改會被永久的保存,即便數據庫崩潰修改後的數據也不會丟失。

隔離級別

SQL 標準中定義了四種隔離級別,這裏簡單介紹一下這四種隔離級別。性能

  • 未提交讀:未提交讀的意思是,事務中的修改,即便沒有提交,對其餘事務也都是可見的,可是這樣會出現髒讀,通常狀況下,一般都不會使用未提交讀。
  • 提交讀:提交讀的意思是,一個事務所作的修改在提交以前對其餘事務都是不可見的,這個級別也叫作「不可重複讀」,由於執行兩次相同的操做,可能會獲得不一樣的結果。
  • 可重複讀:可重複讀解決了髒讀的問題,這個級別保證了同一個事務屢次讀取一樣記錄的結果是一致的,可是這個隔離級別沒法解決幻讀的問題,所謂幻讀就是說,當某個事務讀取範圍數據時,另外一個事務又在該範圍內插入了新的記錄,當以前的事務再次讀取該範圍數據時,會產生幻行。InnoDB 存儲引擎經過 MVCC 解決了幻讀的問題,可重複讀是 MySQL 默認的事務隔離級別。
  • 可串行化:是最高的隔離級別,避免了前面說到的幻讀問題。可串行化會給讀取的每一行都加鎖,因此可能致使大量超時和鎖爭用的問題,實際中不多使用這個隔離級別。

死鎖

死鎖是指兩個或者多個事務在同一資源上相互佔用,並請求鎖定對方佔用的資源。解決死鎖的方法就是回滾一個或者多個事務。spa

MVCC

MVCC 能夠看作是行鎖的一個變種,在不少狀況下 MVCC 能夠避免加鎖,所以開銷更小,不一樣事務型存儲引擎對於 MVCC 的實現各有不一樣。 MVCC 的實現是經過保存數據在某個時間點的快照來實現的。也就是說,無論執行多長時間,每一個事務看到的數據都是一致的。根據事務的開始時間不一樣,每一個事務對同一張表,同一時刻看到的數據多是不同的。這裏簡單介紹一下 InnoDB 的 MVCC。 InnoDB 的 MVCC 經過在每行記錄後面保存兩個隱藏的列來實現。這兩個列,一個保存了行的建立時間,一個保存了行的過時時間,存儲的不是實際的時間,而是版本號。每開始一個新的事務,系統版本號都會自動遞增。事務開始時刻的系統版本號會做爲事務的版本號,用來和查詢到的每行記錄的版本號做對比。下面詳細介紹一下在可重複讀隔離級別下,MVCC 的具體操做。code

  • SELECT
    • InnoDB 會根據如下兩個條件檢查每條記錄:
      • 只查找版本小於等於事務版本號的行
      • 只查找未定義刪除時間或者刪除時間大於事務版本號的行
  • INSERT
    • InnoDB 爲新插入的每一行保存當前的系統版本號做爲行版本號
  • DELETE
    • InnoDB 爲刪除的每一行保存當前的系統版本號做爲行的刪除版本號
  • UPDATE
    • InnoDB 新增一條記錄,保存當前系統版本號做爲新增行的版本號
    • 在被刪除記錄的原始行,保存當前系統版本號做爲被刪除記錄行的刪除版本號

優勢:orm

  1. 由於有了兩個隱藏列來記錄數據的狀態,因此大多數讀操做均可以不加鎖
  2. 性能好,同時能夠保證讀取的數據是正確的

缺點:索引

  1. 須要額外的空間記錄每行的狀態
  2. 須要行狀態的維護和檢查

如何解決幻讀

MVCC 解決幻讀的時候使用了間隙鎖,也就是 next-key lock,這部分就要先從 InnoDB 的三種行鎖提及:事務

  • Record Lock:單個行記錄上的鎖,鎖住的是索引
  • Gap Lock:區間鎖,鎖定一個區間範圍,但不包括記錄自己,開區間
  • Next-Key Lock:間隙鎖,Record Lock + Gap Lock

舉個簡單的例子,資源

select id from user where id > 15 and id < 30
複製代碼

Next-Key Lock

圖示清楚的表示了間隙鎖~

總結

這一章發的貌似有點晚了,應該在索引以前發的。But,依然感謝觀看~ 最後表白我潘,mua! (*╯3╰),七夕快樂~

Reference

《高性能 MySQL》

相關文章
相關標籤/搜索