mysql資料庫學習基礎知識整理

單推小木曾雪菜發表於2020-12-12

主要摘自咕咕評測機:https://blog.csdn.net/doublekillyeye

一、mysql資料庫引擎:

 

 總結:innoDB和myisam主要區別

1.myisam不支援事務,innoDB支援事務

2.innoDB支援外來鍵

3.myisam只有表鎖,而innodb有表鎖、頁鎖、行級鎖(預設行級)

4.innodb支援mvcc

二、ACID原則

原子性:資料庫資料要麼都成功,要麼全部失敗。InnoDB引擎通過undolog保證rollback的時候能找到之前的資料(也就是前面提到的mvcc)

一致性:資料庫資料都是一致的,從一個狀態轉移到另一個狀態,不會出現中間的狀態。通過故障恢復(crash recovery)和double write buffer機制來保證資料庫資料的一致性。

隔離性:隔離性指多個事務可以同時對資料進行修改而不互相影響。(預設是RR(可重複讀)隔離級別)

永久性:事務提交後被持久化到永久儲存.InnoDB通過redolog保證已經commit的資料一定不會丟失,永久儲存在資料庫中。

三、併發帶來的資料庫問題

第一類資料丟失:兩個事務操作同一資料,在一個事務提交後另一個事務回滾了導致這個事務提交的資料丟失了。

髒讀:一個事務可以讀取另外一個事務在未提交事務之前的變更的資料。(讀取到修改但未提交的資料)

第二類資料丟失:兩個事務操作同一資料,一個事務提交後另外一個事務也提交了,導致先提交的事務的資料被覆蓋。

不可重複度:也就是一個事務多次讀取相同行資料得到不同的結果。(讀到別事務已經提交的資料)

幻讀:事務對同一個表前後查詢的資料行數不同(和不可重複讀角度不同,不可重複讀角度在於同一個資料的不同)(讀取到新增且已提交的資料)

四、資料庫隔離級別(解決併發問題)

讀未提交RU:可以讀取未提交的資料,未提交的資料稱為髒資料,所以又稱髒讀。此時:幻讀,不可重複讀和髒讀均允許;(此時兩種資料丟失也不能解決)

讀已提交RC:只能讀取已經提交的資料;此時:允許幻讀和不可重複讀,但不允許髒讀,所以RC隔離級別要求解決髒讀;(此時可以解決第一類更新)

可重複讀RR:同一個事務中多次執行同一個select,讀取到的資料沒有發生改變;此時:允許幻讀,但不允許不可重複讀和髒讀,所以RR隔離級別要求解決不可重複讀;(同時也能解決第二類資料丟失)(MySQL InnoDB 儲存引擎的預設支援的隔離級別

序列化:幻讀,不可重複讀和髒讀都不允許,所以serializable要求解決幻讀;( 分散式事務下一般會使用到

即分別解決(未解決以上任意一種問題)(第一類、髒讀)(第二類、不可重複讀)(幻讀)

  • 不可重複讀的重點是修改:同樣的條件的select, 你讀取過的資料, 再次讀取出來發現值不一樣了
  • 幻讀的重點在於新增或者刪除:同樣的條件的select, 第1次和第2次讀出來的記錄數不一樣

五、鎖機制(建立在Innodb,myISAM,BDB上討論)

表級鎖:開銷小,加鎖快,但是粒度大沖突多,併發讀最低;myisam和bdb,innodb都支援,分為共享鎖 和 排他鎖;不會出現死鎖(一次性獲得所需的全部鎖,要麼全部滿足,要麼全部等待)。

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

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

六、鎖分類

1)表級鎖

  1. 共享鎖(S鎖):如果一個事務T對一個資料A加上共享鎖後,其他事務只能對資料A再次加共享鎖,不能加入排他鎖。加上共享鎖後,只能讀取資料,不能修改資料。
  2. 排他鎖(X鎖):如果一個事務T對一個資料A加上排他鎖後,其他事務不能對資料A進行任何型別的封鎖。加上排他鎖後,既能讀取資料,也能修改資料。
  3. 意向共享鎖(IS):表示事務準備給資料行加上共享鎖,在一個資料行加入共享鎖之前必須獲得該表的意向共享鎖(IS)。
  4. 意向排他鎖(IX): 表示事務準備給資料行加上排他鎖,在一個資料行加上排他鎖之前必須獲得該表的意向排他鎖(IX)。

2)行級鎖

InnoDB的行級鎖是基於索引實現的,如果查詢語句未命中任何索引,那麼InnoDB會使用表級鎖.。

使用鎖的時候,如果表沒有定義任何索引,那麼InnoDB會建立一個隱藏的聚簇索引並使用這個索引來加記錄鎖。

此外,不同於MyISAM總是一次性獲得所需的全部鎖,InnoDB的鎖是逐步獲得的,當兩個事務都需要獲得對方持有的鎖,導致雙方都在等待,這就產生了死鎖。 發生死鎖後,InnoDB一般都可以檢測到,並使一個事務釋放鎖回退,另一個則可以獲取鎖完成事務,我們可以採取以上方式避免死鎖:

  通過表級鎖來減少死鎖產生的概率;
  多個程式儘量約定以相同的順序訪問表(這也是解決併發理論中哲學家就餐問題的一種思路);
  同一個事務儘可能做到一次鎖定所需要的所有資源。

 InnoDB行鎖模式相容性列表

請求鎖模式

   是否相容

當前鎖模式

XIXSIS
X衝突衝突衝突衝突
IX衝突相容衝突相容
S衝突衝突相容相容
IS衝突相容相容相容

間隙鎖行級,使用範圍條件時;對範圍內不存在的記錄加鎖,一是為了防止幻讀、二是為了滿足回覆和負責的需要。當我們用範圍條件而不是相等條件檢索資料,並請求共享或排他鎖時,InnoDB會給符合條件的已有資料記錄的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫做“間隙(GAP)”,InnoDB也會對這個“間隙”加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖)。如果使用相等條件請求給一個不存在的記錄加鎖,InnoDB也會使用間隙鎖!

MyISAM中是不會產生死鎖的,因為MyISAM總是一次性獲得所需的全部鎖,要麼全部滿足,要麼全部等待。而在InnoDB中,鎖是逐步獲得的,就造成了死鎖的可能。

在MySQL中,行級鎖並不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種,如果一條sql語句操作了主鍵索引,MySQL就會鎖定 這條主鍵索引;如果一條語句操作了非主鍵索引,MySQL會先鎖定該非主鍵索引,再鎖定相關的主鍵索引。 在UPDATE、DELETE操作時,MySQL不僅鎖定WHERE條件掃描過的所有索引記錄,而且會鎖定相鄰的鍵值,即所謂的next-key locking。

當兩個事務同時執行,一個鎖住了主鍵索引,在等待其他相關索引。另一個鎖定了非主鍵索引,在等待主鍵索引。這樣就會發生死鎖。

發生死鎖後,InnoDB一般都可以檢測到,並使一個事務釋放鎖回退,另一個獲取鎖完成事務。

鎖競爭

一個程式請求某個 MyISAM表的讀鎖,同時另一個程式也請求同一表的寫鎖,MySQL如何處理呢?答案是寫程式先獲得鎖。不僅如此,即使讀請求先到鎖等待佇列,寫請求後到,寫鎖也會插到讀鎖請求之前!這是因為MySQL認為寫請求一般比讀請求要重要。這也正是MyISAM表不太適合於有大量更新操作和查詢操作應用的原因,因為,大量的更新操作會造成查詢操作很難獲得讀鎖,從而可能永遠阻塞。這種情況有時可能會變得非常糟糕!幸好我們可以通過一些設定來調節MyISAM 的排程行為。
但是可以進行設定。

只有通過索引條件檢索資料,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖!

相關文章