《面試必備,MySQL InnoDB MVCC機制》 MySQL InnoDB MVCC機制吐血總結談到MySQL事務,必然離不開InnoDB和MVCC機制,同時,MVCC也是數據庫面試中的殺手問題,寫這篇總結的目的,就是為了讓自己加深映像,這樣面試就不會忘記了。在搜索時發現關於MVCC的文章真的是參差不齊(老子真的是零零散散看了三個月都迷迷糊糊),所以這裏集合了各家所言之後進行了自我總結,苦苦研究了許久,才得到的比較清晰的認知,這可能也是我目前最有深度的一篇博客了把,希望對我和看到的人都有所幫助,哈哈。MVCC: Multiversion Concurrency Control,翻譯為多版本並發控制,其目標就是為了提高數據庫在高並發場景下的性能。MVCC最大的優勢:讀不加鎖,讀寫不沖突。在讀多寫少的場景下極大的增加了系統的並發性能在講解MVCC之前我們需要先了解MySQL的基本架構,如下圖所示: 圖一MySQL事務MySQL的事務是在存儲引擎層實現的,在MySQL中,我們最常用的就是InnoDB和MyISAM,我們都知道,MYISAM並不支持事務,所以InnoDB實現了MVCC的事務並發處理機制,也是我們這篇文章的主要研究內容。可能我們都看到過,MVCC只在RC和RR下,為了分析這個問題,我們先回顧一下SQL標准事務隔離級別隔離性read uncommitted 讀未提交: 一個事務還沒提交時,它做的變更就能被別的事務看到。read committed 讀提交:一個事務提交之後,它做的變更才會被其他事務看到。repeatable read 可重複讀:一個事務執行過程中看到的數據,總是跟這個事務在啟動時看到的數據是一致的。在可重複讀隔離級別下,未提交變更對其他事務也是不可見的。serializable 串行化 :對於同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。我們通過兩個事務提交流程來說明事務隔離級別的具體效果:我們假設有一個表,僅有一個字段field:DROP TABLE IF EXISTS `mvcc_test`;CREATE TABLE `mvcc_test`( `field` INT)ENGINE=InnoDB;INSERT INTO `mvcc_test` VALUES(1); -- 插入一條數據如下的操作流程: 圖二根據事務隔離級別的定義,我們可以來推測,事務A提交前後,事務B的兩次讀取3和4分別讀取的值:若事務B的隔離級別為 read uncommitted,事務B的兩次讀取都讀取到了20,即修改後的值若事務B的隔離級別是read committed,那麼,事務B的操作3讀取到的值為1,而4讀取到的值為20,因為4時事務A已經完成了提交若事務B的隔離級別是repeatable read或serializable,那麼操作3和4讀取的值都是1。MVCC的必要性MySQL中MYISAM並不支持事務,同樣的, MVCC也就和他沒有半毛錢關系了,InnoDB相比與MYISAM的提升就是對於行級鎖的支持和對事務的支持,而應對高並發事務, MVCC 比單純的加行鎖更有效, 開銷更小。但是單純的並發也會帶來十分嚴重的問題:Lost Update更新丟失: 多個事務對同一行數據進行讀取初值更新時,由於每個事務對其他事務都未感知,會造成最後的更新覆蓋了其他事務所做的更新。dirty read髒讀: 事務一個正在對一條記錄進行修改,在完成並提交前事務二也來讀取該條記錄,事務二讀取了事務一修改但未提交的數據,如果事務一回滾,那麼事務二讀取到的數據就成了“髒”數據。non-repeatable read不可重複讀: 個事務在讀取某些數據後的某個時間再次讀取之前讀取過的數據,發現讀出的數據已經發生了改變或者刪除,這種現象稱為“不可重複讀”phantom read幻讀: 個事務按相同的查詢條件重新讀取以前檢索過的數據,發現其他事務插入了滿足查詢條件的新數據,這種現象稱為“幻讀”不可重複讀與幻讀的現象是比較接近的,也有人直接就說幻讀就是不可重複讀,我比較傾向與他兩就是他兩個: 不可重複讀針對的是值的不同,幻讀指的是數據條數的不同。同樣的對於幻讀,單純的MVCC機制並不能解決幻讀問題,InnoDB也是通過加間隙鎖來防止幻讀。從本質上來說,事務隔離級別就是系統並發能力和數據安全性間的妥協,我們在剛開始學習數據庫時就在說: 隔離性越高,數據庫的性能就越差,就是這個結果,只是我們當時只知其然罷了。解決並發帶來的問題,最通常的就是加鎖,但鎖對於性能也是腰斬性的,所以MVCC就顯得十分重要了。抄大佬的一句話: 在不同的隔離級別下,數據庫通過 MVCC 和隔離級別,讓事務之間並行操作遵循了某種規則,來保證單個事務內前後數據的一致性。InnoDB 下的 MVCC 實現原理在InnoDB中MVCC的實現通過兩個重要的字段進行連接:DB_TRX_ID和DB_ROLL_PT,在多個事務並行操作某行數據的情況下,不同事務對該行數據的UPDATE會產生多個版本,數據庫通過DB_TRX_ID來標記版本,然後用DB_ROLL_PT回滾指針將這些版本以先後順序連接成一條 Undo Log 鏈。對於一個沒有指定PRIMARY KEY的表,每一條記錄的組織大致如下: DB_TRX_ID: 事務id,6byte,每處理一個事務,值自動加一。InnoDB中每個事務有一個唯一的事務ID叫做 transaction id。在事務開始時向InnoDB事務系統申請得到,是按申請順序嚴格遞增的每行數據是有多個版本的,每次事務更新數據時都會生成一個新的數據版本,並且把transaction id賦值給這個數據行的DB_TRX_IDDB_ROLL_PT: 回滾指針,7byte,指向當前記錄的ROLLBACK SEGMENT 的undolog記錄,通過這個指針獲得之前版本的數據。該行記錄上所有舊版本在 undolog 中都通過鏈表的形式組織。還有一個DB_ROW_ID(隱含id,6byte,由innodb自動產生),我們可能聽說過InnoDB下聚簇索引B+Tree的構造規則:如果聲明了主鍵,InnoDB以用戶指定的主鍵構建B+Tree,如果未聲明主鍵,InnoDB 會自動生成一個隱藏主鍵,說的就是DB_ROW_ID。另外,每條記錄的頭信息(record header)裏都有一個專門的bit(deleted_flag)來表示當前記錄是否已經被刪除我們通過圖二的UPDATE(即操作2)來舉例Undo log鏈的構建(假設第一行數據DB_ROW_ID=1):事務A對DB_ROW_ID=1這一行加排它鎖將修改行原本的值拷貝到Undo log中修改目標值,產生一個新版本,將DB_TRX_ID設為當前事務ID即100,將DB_ROLL_PT指向拷貝到Undo log中的舊版本記錄記錄redo log, binlog最終生成的Undo log鏈如下圖所示: 相比與UPDATE,INSERT和DELETE都比較簡單:INSERT: 產生一條新的記錄,該記錄的DB_TRX_ID為當前事務IDDELETE: 特殊的UPDATE,在DB_TRX_ID上記錄下當前事務的ID,同時將delete_flag設為true,在執行commit時才進行刪除操作MVCC的規則大概就是以上所述,那麼它是如何實現高並發下RC和RR的隔離性呢,這就是在MVCC機制下基於生成的Undo log鏈和一致性視圖ReadView來實現的。一致性視圖的生成 ReadView要實現read committed在另一個事務提交之後其他事務可見和repeatable read在一個事務中SELECT操作一致,就是依靠ReadView,對於read uncommitted,直接讀取最新值即可,而serializable采用加鎖的策略通過犧牲並發能力而保證數據安全,因此只有RC和RR這兩個級別需要在MVCC機制下通過ReadView來實現。在read committed級別下,readview會在事務中的每一個SELECT語句查詢發送前生成(也可以在聲明事務時顯式聲明START TRANSACTION WITH CONSISTENT SNAPSHOT),因此每次SELECT都可以獲取到當前已提交事務和自己修改的最新版本。而在repeatable read級別下,每個事務只會在第一個SELECT語句查詢發送前或顯式聲明處生成,其他查詢操作都會基於這個ReadView,這樣就保證了一個事務中的多次查詢結果都是相同的,因為他們都是基於同一個ReadView下進行MVCC機制的查詢操作。InnoDB為每一個事務構造了一個數組m_ids用於保存一致性視圖生成瞬間當前所有活躍事務(開始但未提交事務)的ID,將數組中事務ID最小值記為低水位m_up_limit_id,當前系統中已創建事務ID最大值+1記為高水位m_low_limit_id,構成如圖所示:一致性視圖下查詢操作的流程如下:當查詢發生時根據以上條件生成ReadView,該查詢操作遍曆Undo log鏈,根據當前被訪問版本(可以理解為Undo log鏈中每一個記錄即一個版本,遍曆都是從最新版本向老版本遍曆)的DB_TRX_ID,如果DB_TRX_ID小於m_up_limit_id,則該版本在ReadView生成前就已經完成提交,該版本可以被當前事務訪問。DB_TRX_ID在綠色範圍內的可以被訪問若被訪問版本的DB_TRX_ID大於m_up_limit_id,說明該版本在ReadView生成之後才生成,因此該版本不能被訪問,根據當前版本指向上一版本的指針DB_ROLL_PT訪問上一個版本,繼續判斷。DB_TRX_ID在藍色範圍內的都不允許被訪問若被訪問版本的DB_TRX_ID在 《面試必備,MySQL InnoDB MVCC機制》完,請繼續朗讀精采文章。 喜歡 小編的世界 e4to.com,請記得按讚、收藏及分享!
音調
速度
音量
語言
面試必備,MySQL InnoDB MVCC機制
精確朗讀模式適合大多數瀏覽器,也相容於桌上型與行動裝置。
不過,使用Chorme瀏覽器仍存在一些問題,不建議使用Chorme瀏覽器進行精確朗讀。