日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

MySQL事務(wù)隔離原理

 天下小糧倉 2019-05-08

首先來介紹一下 MySQL 里面的“視圖”的概念。

  • 視圖:查詢語句定義的虛擬表,可以通過 create view ... 來創(chuàng)建。
  • 一致性視圖:InnoDB 實現(xiàn)的,在 MVCC 中用到的,用于支持 RC (Read Commited,讀提交) 和 RR (Repeatable Read,可重復(fù)讀)隔離級別的實現(xiàn)。

一致性視圖工作原理

通過之前的文章我們知道,在可重復(fù)讀隔離級別下,事務(wù)開始前會創(chuàng)建一個一致性視圖。下面我們來詳細(xì)說明一下這個一致性視圖的工作原理。

在InnoDB 引擎中,每個事務(wù)都有一個唯一的ID,就是 transaction id。它是在事務(wù)開始的時候向系統(tǒng)申請的,是嚴(yán)格按順序遞增的。我們知道,每個數(shù)據(jù)行都是有多個版本的。每一次的事務(wù)更新都會有一個新的版本,并且每個版本都有對應(yīng)的 transaction id(row trx_id)。

MySQL事務(wù)隔離原理

上圖是一條行數(shù)據(jù)的多個版本,最新的版本是 V4。但是需要注意的是,上圖中的 U1、U2、U3 對應(yīng)的就是 undo log (回滾日志),小版本 trx_id 的值都是通過 undo log 計算出來的。

按照 可重復(fù)讀的語義,每個事務(wù)啟動的時候只能看到已經(jīng)提交的事務(wù),并且在本事務(wù)執(zhí)行的過程中,不可以讀取到其他事務(wù)的更新操作。在InnoDB 中,為每個事務(wù)構(gòu)造了一個 當(dāng)前事務(wù)ID數(shù)組 的快照,就是記錄事務(wù)開啟時,當(dāng)前正在執(zhí)行的事務(wù)ID 的集合。數(shù)組里面 trx_id 最小的記為 低水位,trx_id 最大的 + 1 記為高水位。如下圖所示:

MySQL事務(wù)隔離原理

對于一個新事務(wù)而言,所讀取到的記錄版本的 trx_id 可能有以下幾種情況:

  • 在綠色區(qū)域:說明數(shù)據(jù)版本在事務(wù)開始前已提交,當(dāng)前版本是可見的。
  • 在紅色區(qū)域:說明數(shù)據(jù)版本在事務(wù)開始后變更的,當(dāng)前版本是不可見的。
  • 在橙色區(qū)域:包含 2 種情況。
  1. 如果 數(shù)據(jù)版本的 trx_id 在數(shù)組中,說明是正在執(zhí)行的事務(wù),不可見。
  2. 如果 數(shù)據(jù)版本的 trx_id 不在數(shù)組中,說明是已經(jīng)提交的事務(wù),可見。

對于 MVCC 的多版本圖,如果當(dāng)前有一個事務(wù),它的低水位是 18 。此時它訪問這個數(shù)據(jù)行時,會通過 V4 版本計算出 V3 的版本。由此我們可以看出,InnoDB 利用了 數(shù)據(jù)多版本的特點,實現(xiàn)了快速創(chuàng)建快照的能力。

我們下面看一個 Demo:1、事務(wù)A 開始前,系統(tǒng)中只有一個 99 的已提交事務(wù);2、事務(wù) A、B、C的版本號分別是 100、101、102,且當(dāng)前系統(tǒng)中只有這 4 個事務(wù);3、事務(wù)開始前,(1, 1) 這一行數(shù)據(jù)的 trx_id 是 90.

MySQL事務(wù)隔離原理

上圖從 事務(wù)A的可重復(fù)讀角度看來,101、102 版本都不可見,因此找到了 90 這個版本的數(shù)據(jù)。

更新操作

前面一段說了,數(shù)據(jù)行多版本的讀取規(guī)則。下面說明一下,更新數(shù)據(jù)的讀取規(guī)則。如下所示:

MySQL事務(wù)隔離原理

上面 事務(wù)B 執(zhí)行的過程中,有事務(wù) C的提交流程。此時事務(wù)B 就不能按照 undo log 回滾到 90 這個版本了(如果是這樣事務(wù)B 執(zhí)行完成數(shù)據(jù)就變成 (1, 2)了,與正確的結(jié)果 (1, 3) 不符)。此時更新的讀取為“當(dāng)前讀”,也就是讀取到最新的數(shù)據(jù),事務(wù)B 執(zhí)行完 k=k+1 后,再次獲取 k 的值時,返回的就是 (1, 3) 了。

上面的過程,我們看到的是 事務(wù)C 在事務(wù)B 執(zhí)行更新之前就已經(jīng)提交了。如果事務(wù)C 沒有提交,那又會是一個什么流程呢?

MySQL事務(wù)隔離原理

從上圖可以看出,如果 事務(wù)C' 沒有提交,那么事務(wù)B 的更新就會等待,知道事務(wù)C' 執(zhí)行完成。

可重復(fù)讀和讀已提交的區(qū)別

在可重復(fù)讀隔離級別下,需要在事務(wù)開啟前創(chuàng)建一個一致性視圖。而讀已提交,則是每執(zhí)行一個語句前都會創(chuàng)建一個新的視圖。


參考:《極客時間:MySQL實戰(zhàn)》、《高性能MySQL》

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多