小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

MySQL事務(wù)隔離原理

 天下小糧倉(cāng) 2019-05-08

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

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

一致性視圖工作原理

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

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

MySQL事務(wù)隔離原理

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

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

MySQL事務(wù)隔離原理

對(duì)于一個(gè)新事務(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ù),可見。

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

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

MySQL事務(wù)隔離原理

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

更新操作

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

MySQL事務(wù)隔離原理

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

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

MySQL事務(wù)隔離原理

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

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

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


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

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多