偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

一篇了解全MVCC

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
在RC隔離級(jí)別下,是每個(gè)快照讀都會(huì)生成并獲取最新的Read View,而在RR隔離級(jí)別下,則是同一個(gè)事務(wù)中的第一個(gè)快照讀才會(huì)創(chuàng)建Read View,之后的快照讀獲取的都是同一個(gè)Read View。

一、什么是MVCC

MVCC,全稱Multi-Version Concurrency Control,即多版本并發(fā)控制,是一種并發(fā)控制的方法,一般用在數(shù)據(jù)庫(kù)管理系統(tǒng)中,實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的并發(fā)訪問,比如在MySQL InnoDB中主要是為了提高數(shù)據(jù)庫(kù)并發(fā)性能,不用加鎖,非阻塞并發(fā)讀。MVCC多版本并發(fā)控制指的是維持一個(gè)數(shù)據(jù)的多個(gè)版本,使得讀寫操作沒有沖突,快照讀是MySQL為實(shí)現(xiàn)MVCC的一個(gè)非阻塞讀功能。

二、解決的問題是什么

1.三種數(shù)據(jù)庫(kù)并發(fā)場(chǎng)景:

讀讀:不會(huì)有問題,也不需要并發(fā)控制

讀寫:有線程安全問題,可能會(huì)造成事務(wù)隔離性問題,可能遇到臟讀、幻讀、不可重復(fù)讀

寫寫:有線程安全問題,可能存在更新丟失問題

2.解決問題

MVCC是一種用來(lái)解決讀寫沖突的無(wú)鎖并發(fā)控制,也就是為事務(wù)分配單項(xiàng)增長(zhǎng)的時(shí)間戳,為每個(gè)修改保存一個(gè)版本,版本與事務(wù)時(shí)間戳關(guān)聯(lián),讀操作只讀該事務(wù)開始前的數(shù)據(jù)庫(kù)的快照(隔離級(jí)別RC下),所以MVCC為數(shù)據(jù)庫(kù)解決了以下問題:

在并發(fā)讀寫數(shù)據(jù)庫(kù)時(shí),可以做到在讀操作時(shí)不用阻塞寫操作,寫操作也不用阻塞讀操作,提高了數(shù)據(jù)庫(kù)并發(fā)讀寫的性能

解決臟讀、幻讀、不可重復(fù)讀等事務(wù)隔離問題,但是不能解決更新丟失問題

三、實(shí)現(xiàn)原理

主要依賴于記錄中的三個(gè)隱藏字段、undolog,read view來(lái)實(shí)現(xiàn)的。

1.隱藏字段

每行記錄,除了我們自定義的字段外,還有數(shù)據(jù)庫(kù)隱式定義的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段:

DB_ROW_ID:6字節(jié),隱藏的主鍵,如果數(shù)據(jù)表沒有主鍵,那么innodb會(huì)自動(dòng)生成一個(gè)6字節(jié)的row_id

DB_TRX_ID:6字節(jié),最近修改事務(wù)id,記錄創(chuàng)建這條記錄或者最后一次修改該記錄的事務(wù)id

DB_ROLL_PTR:7字節(jié),回滾指針,用于配合undo日志,指向上一個(gè)舊版本

假設(shè)記錄如圖所示:

2.undolog

1)概念

回滾日志,表示在進(jìn)行insert,delete,update操作的時(shí)候產(chǎn)生的方便回滾的日志。

2)說(shuō)明

當(dāng)進(jìn)行insert操作的時(shí)候,產(chǎn)生的undolog,只在事務(wù)回滾的時(shí)候需要用到,并且在事務(wù)提交之后可以被立刻丟棄。

當(dāng)進(jìn)行update和delete操作的時(shí)候,產(chǎn)生的undolog,不僅僅在事務(wù)回滾的時(shí)候需要,在快照讀的時(shí)候也需要,所以不能隨便刪除,只有在快照讀或事務(wù)回滾不涉及該日志時(shí),對(duì)應(yīng)的日志才會(huì)被purge線程統(tǒng)一清除。

當(dāng)數(shù)據(jù)發(fā)生更新和刪除操作的時(shí)候,實(shí)際只是設(shè)置了舊記錄的deleted_bit,并不是將過(guò)時(shí)的記錄刪除,因?yàn)闉榱斯?jié)省磁盤空間,innodb有專門的purge線程來(lái)清除deleted_bit為true的記錄,如果某個(gè)記錄的deleted_id為true,并且DB_TRX_ID相對(duì)于purge線程的read view 可見,那么這條記錄就是可以被清除的。

3)undolog生成的記錄鏈表

(1)假設(shè)有一個(gè)事務(wù)編號(hào)為1的事務(wù)向表中插入一條記錄,那么此時(shí)行數(shù)據(jù)如下,主鍵id=1,事務(wù)id=1

(2)假設(shè)有第二個(gè)事務(wù)(編號(hào)為2)對(duì)該記錄的name做出修改,改為lisi

底層操作:在事務(wù)2修改該行記錄數(shù)據(jù)時(shí)1、對(duì)該數(shù)據(jù)行加排他鎖2、把該行數(shù)據(jù)拷貝到undolog中,作為舊記錄3、修改該行name為lisi,并且修改事務(wù)id=2,回滾指針指向拷貝到undolog的副本記錄中4、提交事務(wù),釋放鎖。

(3)假設(shè)有第三個(gè)事務(wù)(編號(hào)為3)對(duì)該記錄的age做了修改,改為32。

底層操作:在事務(wù)3修改該行記錄數(shù)據(jù)時(shí)1、對(duì)該數(shù)據(jù)行加排他鎖2、把該行數(shù)據(jù)拷貝到undolog中,作為舊記錄,發(fā)現(xiàn)該行記錄已經(jīng)有undolog了,那么最新的舊數(shù)據(jù)作為鏈表的表頭,插在該行記錄的undolog最前面3、修改該行age為32歲,并且修改事務(wù)id=3,回滾指針指向剛剛拷貝的undolog的副本記錄4、提交事務(wù),釋放鎖。

。從上述的一系列圖中,可以發(fā)現(xiàn),不同事務(wù)或者相同事務(wù)的對(duì)同一記錄的修改,會(huì)導(dǎo)致該記錄的undolog生成一條記錄版本鏈表,undolog的表頭就是最新的舊記錄,表尾就是最早的舊記錄。

3.read view

Read View是事務(wù)進(jìn)行快照讀操作的時(shí)候生產(chǎn)的讀視圖,在該事務(wù)執(zhí)行快照讀的那一刻,系統(tǒng)會(huì)生成一個(gè)此刻的快照,記錄并維護(hù)系統(tǒng)此刻活躍事務(wù)的id,用來(lái)做可見性判斷的,也就是說(shuō)當(dāng)某個(gè)事務(wù)在執(zhí)行快照讀的時(shí)候,對(duì)該記錄創(chuàng)建一個(gè)Read View的視圖,把它當(dāng)作條件去判斷當(dāng)前事務(wù)能夠看到哪個(gè)版本的數(shù)據(jù),有可能讀取到的是最新的數(shù)據(jù),也有可能讀取到的是當(dāng)前行記錄的undolog中某個(gè)版本的數(shù)據(jù)。

1)可見性算法

將要被修改的數(shù)據(jù)的最新記錄中的DB_TRX_ID(當(dāng)前事務(wù)id)取出來(lái),與系統(tǒng)此刻其他活躍事務(wù)的id去對(duì)比,如果DB_TRX_ID跟Read View的屬性做了比較,不符合可見性,那么就通過(guò)DB_ROLL_PTR回滾指針去取出undolog中的DB_TRX_ID做比較,即遍歷鏈表中的DB_TRX_ID,直到找到滿足條件的DB_TRX_ID,這個(gè)DB_TRX_ID所在的舊記錄就是當(dāng)前事務(wù)能看到的數(shù)據(jù)。

2)可見性規(guī)則

首先要知道Read View中的三個(gè)全局屬性:

  • trx_list:一個(gè)數(shù)值列表,用來(lái)維護(hù)Read View生成時(shí)刻系統(tǒng)正活躍的事務(wù)ID(1,2,3)
  • up_limit_id:記錄trx_list列表中事務(wù)ID最小的ID(1)
  • low_limit_id:Read View生成時(shí),系統(tǒng)即將分配的下一個(gè)事務(wù)ID(4)

具體的比較規(guī)則如下:

首先比較DB_TRX_ID < up_limit_id如果小于,則當(dāng)前事務(wù)能看到DB_TRX_ID所在的記錄如果大于等于,則進(jìn)入下一個(gè)判斷。

接下來(lái)判斷DB_TRX_ID >= low_limit_id如果大于等于,則代表DB_TRX_ID所在的記錄在Read View生成后才出現(xiàn)的,那么對(duì)于當(dāng)前事務(wù)不可見如果小于,則進(jìn)入下一步判斷。

判斷DB_TRX_ID是否在活躍事務(wù)中,trx_list包含DB_TRX_ID如果包含,則代表在Read View生成的時(shí)候,這個(gè)事務(wù)還是活躍狀態(tài),未commit的數(shù)據(jù),當(dāng)前事務(wù)也是看不到如果不包含,則說(shuō)明這個(gè)事務(wù)在Read View生成之前就已經(jīng)開始commit,那么修改的結(jié)果是能夠看見的。

流程圖如下:

總結(jié):兩種情況可見

  • DB_TRX_ID < up_limit_id
  • DB_TRX_ID不在trx_list范圍內(nèi),且小于low_limit_id

四、整個(gè)流程

假設(shè)有四個(gè)事務(wù)同時(shí)在執(zhí)行,如下圖所示:

事務(wù)1

事務(wù)2

事務(wù)3

事務(wù)4

事務(wù)開始

事務(wù)開始

事務(wù)開始

事務(wù)開始

修改且已提交

進(jìn)行中

快照讀

進(jìn)行中



從上述表格中,我們可以看到,當(dāng)事務(wù)2對(duì)某行數(shù)據(jù)執(zhí)行了快照讀,數(shù)據(jù)庫(kù)為該行數(shù)據(jù)生成一個(gè)Read View視圖,可以看到事務(wù)1和事務(wù)3還在活躍狀態(tài),事務(wù)4在事務(wù)2快照讀的前一刻提交了更新,所以在Read View中記錄了系統(tǒng)當(dāng)前活躍事務(wù)1,3,維護(hù)在一個(gè)列表中。同時(shí)可以看到up_limit_id的值為1,而low_limit_id為5,如下圖所示:

在上述的例子中,只有事務(wù)4修改過(guò)該行記錄,并且在事務(wù)2進(jìn)行快照讀前,就提交了事務(wù),所以該行當(dāng)前數(shù)據(jù)的undolog如下所示:

當(dāng)事務(wù)2在快照讀該行記錄時(shí),會(huì)拿著該行記錄的DB_TRX_ID去跟up_limit_id、lower_limit_id和活躍事務(wù)列表進(jìn)行比較,從而判讀事務(wù)2能看到該行記錄的版本是哪個(gè)。具體流程如下:

拿該行記錄的事務(wù)ID(4)去跟Read View中的up_limit_id(1)相比較,判斷是否小于,通過(guò)對(duì)比發(fā)現(xiàn)不小于,所以不符合條件

繼續(xù)判斷4是否大于等于low_limit_id(5),通過(guò)比較發(fā)現(xiàn)也不大于,所以不符合條件。

判斷事務(wù)4是否處理trx_list列表中,發(fā)現(xiàn)不在列表中,那么符合可見性條件。

所以事務(wù)4修改后提交的最新結(jié)果對(duì)事務(wù)2的快照是可見的,因此事務(wù)2讀取到的最新數(shù)據(jù)記錄是事務(wù)4所提交的版本,而事務(wù)4提交的版本也是全局角度的最新版本。

五、拓展

1、當(dāng)前讀

讀取的是最新版本的記錄,讀取時(shí)還要保證其它并發(fā)事務(wù)不能修改當(dāng)前記錄,會(huì)對(duì)讀取的記錄進(jìn)行加鎖。

共享鎖:select lock in share mode。

排它鎖:select for update 、update、 insert 、delete。

2、快照/普通讀

1)概念

像不加鎖的select操作,就是快照讀,即非阻塞讀。

2)為什么會(huì)出現(xiàn)快照讀?

是基于提高并發(fā)性能的考慮,快照讀是基于多版本并發(fā)控制,即MVCC,可以認(rèn)為MVCC是行鎖的一個(gè)變種,但它在很多情況下,避免了加鎖操作,降低了開銷;

3)存在問題

基于多版本,讀到的并不一定是數(shù)據(jù)的最新版本,可能是之前的歷史版本。

串行級(jí)別下的快照讀會(huì)退化成當(dāng)前讀

3、RC、RR級(jí)別下的InnoDB快照讀有什么不同

因?yàn)镽ead View生成時(shí)機(jī)的不同,從而造成RC、RR級(jí)別下快照讀的結(jié)果的不同。

在RC級(jí)別下,事務(wù)中,每次快照讀都會(huì)新生成一個(gè)快照和Read View,這就是我們?cè)赗C級(jí)別下的事務(wù)中可以看到別的事務(wù)提交的更新的原因。

在RR級(jí)別下,某個(gè)事務(wù)的對(duì)某條記錄的第一次快照讀會(huì)創(chuàng)建一個(gè)快照(Read View),將當(dāng)前系統(tǒng)活躍的其他事務(wù)記錄起來(lái),此后在調(diào)用快照讀的時(shí)候,還是使用的是同一個(gè)Read View,所以只要當(dāng)前事務(wù)在其他事務(wù)提交更新之前使用過(guò)快照讀,那么之后的快照讀使用的都是同一個(gè)Read View,之后的修改對(duì)其不可見。

總結(jié):在RC隔離級(jí)別下,是每個(gè)快照讀都會(huì)生成并獲取最新的Read View,而在RR隔離級(jí)別下,則是同一個(gè)事務(wù)中的第一個(gè)快照讀才會(huì)創(chuàng)建Read View,之后的快照讀獲取的都是同一個(gè)Read View。

4、 RR級(jí)別下怎么避免幻讀

快照讀,和避免不可重復(fù)讀原理一樣,可以避免幻讀。

當(dāng)前讀,因?yàn)槊看味际亲x取新的快照,如果需要避免,可以通過(guò)加鎖限制新增或刪除相同條件的數(shù)據(jù)?

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2022-12-19 08:14:30

注解開發(fā)配置

2021-05-20 06:57:16

RabbitMQ開源消息

2024-01-09 12:06:55

MVCC并發(fā)控制MySQL

2021-10-28 19:15:02

IPUARM

2021-07-10 09:02:42

編程語(yǔ)言 TypeScript

2021-07-14 10:08:30

責(zé)任鏈模式加工鏈

2020-10-09 08:15:11

JsBridge

2021-12-30 09:38:51

DDoS攻擊防范

2022-06-08 00:10:33

數(shù)據(jù)治理框架

2021-07-14 08:24:23

TCPIP 通信協(xié)議

2021-06-30 00:20:12

Hangfire.NET平臺(tái)

2023-05-12 08:19:12

Netty程序框架

2021-08-11 07:02:21

npm包管理器工具

2021-07-28 10:02:54

建造者模式代碼

2021-10-30 07:55:00

BLE 藍(lán)牙開發(fā)

2021-11-24 08:51:32

Node.js監(jiān)聽函數(shù)

2022-07-31 20:00:59

云原生云計(jì)算

2021-08-02 06:34:55

Redis刪除策略開源

2021-12-15 11:52:34

GPLLinuxGNU

2021-11-08 08:42:44

CentOS Supervisor運(yùn)維
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)