久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

數(shù)據(jù)庫(kù)并發(fā)控制的作用及示例分析

共計(jì) 7326 個(gè)字符,預(yù)計(jì)需要花費(fèi) 19 分鐘才能閱讀完成。

數(shù)據(jù)庫(kù)并發(fā)控制的作用及示例分析,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

1. 數(shù)據(jù)庫(kù)并發(fā)控制的作用

1.1 事務(wù)的概念

在介紹并發(fā)控制前,首先需要了解事務(wù)。數(shù)據(jù)庫(kù)提供了增刪改查等幾種基礎(chǔ)操作,用戶(hù)可以靈活地組合這幾種操作,實(shí)現(xiàn)復(fù)雜的語(yǔ)義。在很多場(chǎng)景下,用戶(hù)希望一組操作可以做為一個(gè)整體一起生效,這就是事務(wù)。事務(wù)是數(shù)據(jù)庫(kù)狀態(tài)變更的基本單元,包含一個(gè)或多個(gè)操作 (例如多條 SQL 語(yǔ)句)。經(jīng)典的轉(zhuǎn)賬事務(wù),就包括三個(gè)操作:(1) 檢查 A 賬戶(hù)余額是否足夠。(2)如果足夠,從 A 扣減 100 塊。(3)B 賬戶(hù)增加 100 塊。

事務(wù)有個(gè)基本特性:這一組操作要么一起生效,要么都不生效,事務(wù)執(zhí)行過(guò)程中如遇錯(cuò)誤,已經(jīng)執(zhí)行的操作要全部撤回,這就是事務(wù)的原子性。如果失敗發(fā)生后,部分生效的事務(wù)無(wú)法撤回,那數(shù)據(jù)庫(kù)就進(jìn)入了不一致?tīng)顟B(tài),與真實(shí)世界的事實(shí)相左。例如轉(zhuǎn)賬事務(wù)從 A 賬戶(hù)扣款 100 塊后失敗了,B 賬戶(hù)還未增加款項(xiàng),如果 A 賬戶(hù)扣款操作未撤回,這個(gè)世界就莫名奇妙丟失了 100 塊。原子性可以通過(guò)記日志 (更改前的值) 來(lái)實(shí)現(xiàn),還有一些數(shù)據(jù)庫(kù)將事務(wù)操作緩存在本地,如遇失敗,直接丟棄緩存里的操作。

事務(wù)只要提交了,它的結(jié)果就不能改變了,即使遇到系統(tǒng)宕機(jī),重啟后數(shù)據(jù)庫(kù)的狀態(tài)與宕機(jī)前一致,這就是事務(wù)的持久性。數(shù)據(jù)只要存儲(chǔ)非易失存儲(chǔ)介質(zhì),宕機(jī)就不會(huì)導(dǎo)致數(shù)據(jù)丟失。因此數(shù)據(jù)庫(kù)可以采用以下方法來(lái)保證持久性:(1)事務(wù)完成前,所有的更改都保證存儲(chǔ)到磁盤(pán)上了。或 (2) 提交完成前,事務(wù)的更改信息,以日志的形式存儲(chǔ)在磁盤(pán),重啟過(guò)程根據(jù)日志恢復(fù)出數(shù)據(jù)庫(kù)系統(tǒng)的內(nèi)存狀態(tài)。一般而言,數(shù)據(jù)庫(kù)會(huì)選擇方法(2),原因留給讀者思考。

數(shù)據(jù)庫(kù)為了提高資源利用率和事務(wù)執(zhí)行效率、降低響應(yīng)時(shí)間,允許事務(wù)并發(fā)執(zhí)行。但是多個(gè)事務(wù)同時(shí)操作同一對(duì)象,必然存在沖突,事務(wù)的中間狀態(tài)可能暴露給其它事務(wù),導(dǎo)致一些事務(wù)依據(jù)其它事務(wù)中間狀態(tài),把錯(cuò)誤的值寫(xiě)到數(shù)據(jù)庫(kù)里。需要提供一種機(jī)制,保證事務(wù)執(zhí)行不受并發(fā)事務(wù)的影響,讓用戶(hù)感覺(jué),當(dāng)前仿佛只有自己發(fā)起的事務(wù)在執(zhí)行,這就是隔離性。隔離性讓用戶(hù)可以專(zhuān)注于單個(gè)事務(wù)的邏輯,不用考慮并發(fā)執(zhí)行的影響。數(shù)據(jù)庫(kù)通過(guò)并發(fā)控制機(jī)制保證隔離性。由于隔離性對(duì)事務(wù)的執(zhí)行順序要求較高,很多數(shù)據(jù)庫(kù)提供了不同選項(xiàng),用戶(hù)可以犧牲一部分隔離性,提升系統(tǒng)性能。這些不同的選項(xiàng)就是事務(wù)隔離級(jí)別。

數(shù)據(jù)庫(kù)反映的是真實(shí)世界,真實(shí)世界有很多限制,例如:賬戶(hù)之間無(wú)論怎么轉(zhuǎn)賬,總額不會(huì)變等現(xiàn)實(shí)約束; 年齡不能為負(fù)值,性別最多只能有男、女、跨性別者三種選項(xiàng)等完整性約束。事務(wù)執(zhí)行,不能打破這些約束,保證事務(wù)從一個(gè)正確的狀態(tài)轉(zhuǎn)移到另一個(gè)正確的狀態(tài),這就是一致性。不同與前三種性質(zhì)完全由數(shù)據(jù)庫(kù)實(shí)現(xiàn)保證,一致性既依賴(lài)于數(shù)據(jù)庫(kù)實(shí)現(xiàn)(原子性、持久性、隔離性也是為了保證一致性),也依賴(lài)于應(yīng)用端編寫(xiě)的事務(wù)邏輯。

1.2 事務(wù)并發(fā)控制如何保證隔離性

為了保證隔離性,一種方式是所有事務(wù)串行執(zhí)行,讓事務(wù)之間不互相干擾。但是串行執(zhí)行效率非常低,為了增大吞吐,減小響應(yīng)時(shí)間,數(shù)據(jù)庫(kù)通常允許多個(gè)事務(wù)同時(shí)執(zhí)行。因此并發(fā)控制模塊需要保證:事務(wù)并發(fā)執(zhí)行的效果,與事務(wù)串行執(zhí)行的效果完全相同(serializability),以達(dá)到隔離性的要求。

為了方便描述并發(fā)控制如何保證隔離性,我們簡(jiǎn)化事務(wù)模型。事務(wù)是由一個(gè)或多個(gè)操作組成,所有的操作最終都可以拆分為一系列讀和寫(xiě)。一批同時(shí)發(fā)生的事務(wù),所有讀、寫(xiě)的一種執(zhí)行順序,被定義為一個(gè) schedule,例如:

T1、T2 同時(shí)執(zhí)行,一個(gè)可能的 schedule: T1.read(A),T2.read(B),T1.write(A),T1.read(B),T2.write(A)

如果并發(fā)事務(wù)執(zhí)行的 schedule 效果與串行執(zhí)行的 schedule(serial  schedule)等價(jià),就可以滿足 serializability。一個(gè) schedule 不斷調(diào)換讀寫(xiě)操作的順序,總會(huì)變成一個(gè) serializable  schedule,但是有的調(diào)換可能導(dǎo)致事務(wù)執(zhí)行的結(jié)果不一樣。一個(gè) schedule 中,相鄰的兩個(gè)操作調(diào)換位置導(dǎo)致事務(wù)結(jié)果變化,那么這兩個(gè)操作就是沖突的。沖突需要同時(shí)滿足以下條件:

1. 這兩個(gè)操作來(lái)自不同事務(wù)

2. 至少有一個(gè)是寫(xiě)操作

3. 操作對(duì)象相同

因此常見(jiàn)的沖突包括:

讀寫(xiě)沖突。事務(wù)先 A 讀取某行數(shù)據(jù)、事務(wù) B 后修改該行數(shù)據(jù),和事務(wù) B 先修改某行事務(wù)、事務(wù) A 后讀該行記錄兩種 schedule。事務(wù) A 讀到的結(jié)果不同。這種沖突可能會(huì)導(dǎo)致不可重復(fù)讀異象和臟讀異象。

寫(xiě)讀沖突。與讀寫(xiě)沖突產(chǎn)生的原因相同。這種沖突可能會(huì)導(dǎo)致臟讀異象。

寫(xiě)寫(xiě)沖突。兩個(gè)操作先后寫(xiě)一個(gè)對(duì)象,后一個(gè)操作的結(jié)果決定了寫(xiě)入的最終結(jié)果。這種沖突可能會(huì)導(dǎo)致更新丟失異象。

數(shù)據(jù)庫(kù)只要保證,并發(fā)事務(wù)的 schedule,保持沖突操作的執(zhí)行順序不變,只調(diào)換不沖突的操作,可以成為 serial  schedule,就可以認(rèn)為它們等價(jià)。這種等價(jià)判斷方式叫做 conflict equivalent:兩個(gè) schedule 的沖突操作順序相同。例如下圖的例子,T1  write(A)與 T3 read(A)沖突,且 T1 先于 T3 發(fā)生。T1 read(B)和 T2  write(B)沖突,且 T2 先于 T1,因此左圖事務(wù)執(zhí)行的 schedule,與 T2,T1,T3 串行執(zhí)行的 serial schedule(右圖)   等價(jià)。左圖的執(zhí)行順序滿足 conflict serializablity。

再分析一個(gè)反例:T1 read(A)與 T2 write(A)沖突且 T1 先于 T2,T2 write(A)與 T2  write(A)沖突且 T2 先于 T1。下圖這個(gè)個(gè) schedule 無(wú)法與任何一個(gè) serial schedule 等價(jià),是一個(gè)不滿足 conflict  serializablity 的執(zhí)行順序,會(huì)造成更新丟失的異象。

總體來(lái)說(shuō),serializability 是比較嚴(yán)格的要求,為了提高數(shù)據(jù)庫(kù)系統(tǒng)的并發(fā)性能,很多用戶(hù)愿意去降低隔離性的要求以尋求更好的性能。數(shù)據(jù)庫(kù)系統(tǒng)往往會(huì)實(shí)現(xiàn)多種隔離級(jí)別,供用戶(hù)靈活選擇,關(guān)于事務(wù)隔離級(jí)別,可以參看這篇文章。

并發(fā)控制的要求清楚了,如何實(shí)現(xiàn)呢? 后文將依據(jù)沖突檢測(cè)的樂(lè)觀程度,一一介紹并發(fā)控制常見(jiàn)的實(shí)現(xiàn)方法。

2. 基于兩階段鎖的并發(fā)控制

2.1 2PL

既然要保證操作按正確的順序執(zhí)行,最容易想到的方法就是加鎖保護(hù)訪問(wèn)對(duì)象。數(shù)據(jù)庫(kù)系統(tǒng)的鎖管理器模塊,專(zhuān)門(mén)負(fù)責(zé)給訪問(wèn)對(duì)象加鎖和釋放鎖,保證只有持有鎖的事務(wù),才能操作相應(yīng)的對(duì)象。鎖可以分為兩類(lèi):S-Lock 和 X -Lock,S-Lock 是讀請(qǐng)求使用的共享鎖,X-Lock 是寫(xiě)請(qǐng)求使用的排他鎖。它們的兼容性如下:操作同一個(gè)對(duì)象,只有兩個(gè)讀請(qǐng)求相互兼容,可以同時(shí)執(zhí)行,讀寫(xiě)和寫(xiě)寫(xiě)操作都會(huì)因?yàn)殒i沖突而串行執(zhí)行。

2PL(Two-phase locking)是數(shù)據(jù)庫(kù)最常見(jiàn)的基于鎖的并發(fā)控制協(xié)議,顧名思義,它包含兩個(gè)階段:

階段一:Growing,事務(wù)向鎖管理器請(qǐng)求它需要的所有鎖(存在加鎖失敗的可能)。

階段二:Shrinking,事務(wù)釋放 Growing 階段獲取的鎖,不允許再請(qǐng)求新鎖。

為什么加鎖和放鎖要涇渭分明地分為兩個(gè)階段呢?

2PL 并發(fā)控制目的是為了達(dá)到 serializable,如果并發(fā)控制不事先將所有需要的鎖申請(qǐng)好,而是釋放鎖后,還允許再次申請(qǐng)鎖,可能出現(xiàn)事務(wù)內(nèi)兩次操作同一對(duì)象之間,其它事務(wù)修改這一對(duì)象(如下圖所示),進(jìn)而無(wú)法達(dá)到 conflict  serializable,出現(xiàn)不一致的現(xiàn)象(下面的例子是 lost update)。

2PL 可以保證 conflict  serializability,因?yàn)槭聞?wù)必須拿到所有需要的鎖才能執(zhí)行。例如正在執(zhí)行的事務(wù) A 與事務(wù) B 沖突,事務(wù) B 要么已經(jīng)執(zhí)行完,要么還在等待。因此那些沖突操作的執(zhí)行順序,與 BA 或 AB 串行執(zhí)行時(shí)沖突操作執(zhí)行順序一致。

所以,數(shù)據(jù)庫(kù)只要采用 2PL 就能保證一致性和隔離性了嗎? 來(lái)看一下這個(gè)例子:

以上執(zhí)行順序是符合 2PL 的,但 T2 讀到了未提交的數(shù)據(jù)。如果此時(shí) T1 回滾,則會(huì)引發(fā)級(jí)聯(lián)回滾(T1 的更改,不能被任何事務(wù)看到)。因此,數(shù)據(jù)庫(kù)往往使用的是加強(qiáng)版的 S(trong)S(trict)2PL,它相較于 2PL 有一點(diǎn)不同:shrinking 階段,只能在事務(wù)結(jié)束后再釋放鎖,完全杜絕了事務(wù)未提交的數(shù)據(jù)被讀到。

2.2 死鎖處理

并發(fā)事務(wù)加鎖放鎖必然繞不開(kāi)一個(gè)問(wèn)題 – 死鎖:事務(wù) 1 持有 A 鎖等 B 鎖,事務(wù) 2 持有 B 鎖等 A 鎖。目前解決死鎖問(wèn)題有兩種方案:

Deadlock Detection:

數(shù)據(jù)庫(kù)系統(tǒng)根據(jù) waits-for 圖記錄事務(wù)的等待關(guān)系,其中點(diǎn)代表事務(wù),有向邊代表事務(wù)在等待另一個(gè)事務(wù)放鎖。當(dāng) waits-for 圖出現(xiàn)環(huán)時(shí),代表死鎖出現(xiàn)了。系統(tǒng)后臺(tái)會(huì)定時(shí)檢測(cè) waits-for 圖,如果發(fā)現(xiàn)環(huán),則需要選擇一個(gè)合適的事務(wù) abort。

Deadlock Prevention:

當(dāng)事務(wù)去請(qǐng)求一個(gè)已經(jīng)被持有的鎖時(shí),數(shù)據(jù)庫(kù)系統(tǒng)為防止死鎖,殺死其中一個(gè)事務(wù)(一般持續(xù)越久的事務(wù),保留的優(yōu)先級(jí)越高)。這種防患于未然的方法不需要 waits-for 圖,但提高了事務(wù)被殺死的比率。

2.3 意向鎖

如果只有行鎖,那么事務(wù)要更新一億條記錄,需要獲取一億個(gè)行鎖,將占用大量的內(nèi)存資源。我們知道鎖是用來(lái)保護(hù)數(shù)據(jù)庫(kù)內(nèi)部訪問(wèn)對(duì)象的,這些對(duì)象根據(jù)大小可能是:屬性(Attribute)、記錄(Tuple)、頁(yè)面(Page)、表(Table),相應(yīng)的鎖可分為行鎖、頁(yè)面鎖、表鎖(沒(méi)人實(shí)現(xiàn)屬性鎖,對(duì)于 OLTP 數(shù)據(jù)庫(kù),最小的操作單元是行)。對(duì)于事務(wù)來(lái)講,獲得最少量的鎖當(dāng)然是最好的,比如更新一億條記錄,或許加一個(gè)表鎖就足夠了。

層次越高的鎖 (如表鎖),可以有效減少對(duì)資源的占用,顯著減少鎖檢查的次數(shù),但會(huì)嚴(yán)重限制并發(fā)。層次越低的鎖(如行鎖),有利于并發(fā)執(zhí)行,但在事務(wù)請(qǐng)求對(duì)象多的情況下,需要大量的鎖檢查。數(shù)據(jù)庫(kù)系統(tǒng)為了解決高層次鎖限制并發(fā)的問(wèn)題,引入了意向(Intention) 鎖的概念:

Intention-Shared (IS):表明其內(nèi)部一個(gè)或多個(gè)對(duì)象被 S -Lock 保護(hù),例如某表加 IS,表中至少一行被 S -Lock 保護(hù)。

Intention-Exclusive (IX):表明其內(nèi)部一個(gè)或多個(gè)對(duì)象被 X -Lock 保護(hù)。例如某表加 IX,表中至少一行被 X -Lock 保護(hù)。

Shared+Intention-Exclusive  (SIX):表明內(nèi)部至少一個(gè)對(duì)象被 X -Lock 保護(hù),并且自身被 S -Lock 保護(hù)。例如某個(gè)操作要全表掃描,并更改表中幾行,可以給表加 SIX。讀者可以思考一下,為啥沒(méi)有 XIX 或 XIS

意向鎖和普通鎖的兼容關(guān)系如下所示:

意向鎖的好處在于:當(dāng)表加了 IX,意味著表中有行正在修改。(1)這時(shí)對(duì)表發(fā)起 DDL 操作,需要請(qǐng)求表的 X 鎖,那么看到表持有 IX 就直接等待了,而不用逐個(gè)檢查表內(nèi)的行是否持有行鎖,有效減少了檢查開(kāi)銷(xiāo)。(2)這時(shí)有別的讀寫(xiě)事務(wù)過(guò)來(lái),由于表加的是 IX 而非 X,并不會(huì)阻止對(duì)行的讀寫(xiě)請(qǐng)求(先在表上加 IX,再去記錄上加 S /X),事務(wù)如果沒(méi)有涉及已經(jīng)加了 X 鎖的行,則可以正常執(zhí)行,增大了系統(tǒng)的并發(fā)度。

3. 基于 Timing Order(T/O)的并發(fā)控制

為每個(gè)事務(wù)分配 timestamp,并以此決定事務(wù)執(zhí)行順序。當(dāng)事務(wù) 1 的 timestamp 小于事務(wù) 2 時(shí),數(shù)據(jù)庫(kù)系統(tǒng)要保證事務(wù) 1 先于事務(wù) 2 執(zhí)行。timestamp 分配的方式包括:(1)物理時(shí)鐘;(2)邏輯時(shí)鐘;(2)混合時(shí)鐘。

3.1 Basic T/O

基于 T / O 的并發(fā)控制,讀寫(xiě)不需加鎖,  每行記錄都標(biāo)記了最后修改和讀取它的事務(wù)的 timestamp。當(dāng)事務(wù)的 timestamp 小于記錄的 timestamp 時(shí) (不能讀到”未來(lái)的”數(shù)據(jù)),需要 abort 后重新執(zhí)行。假設(shè)記錄 X 上標(biāo)記了讀寫(xiě)兩個(gè) timestamp:WTS(X) 和 RTS(X),事務(wù)的 timestamp 為 TTS,可見(jiàn)性判斷如下:

讀:

TTS WTS(X):該對(duì)象對(duì)該事務(wù)不可見(jiàn),abort 事務(wù),取一個(gè)新 timestamp 重新開(kāi)始。

TTS WTS(X):該對(duì)象對(duì)事務(wù)可見(jiàn),更新 RTS(X) = max(TTS,RTS(X))。為了滿足 repeatable  read,事務(wù)復(fù)制 X 的值。

為了防止讀到臟數(shù)據(jù),可以在記錄上做特殊標(biāo)記,讀請(qǐng)求需等待事務(wù)提交后再去讀。

寫(xiě):

TTS WTS(X) || TTS RTS(X):abort 事務(wù),重新開(kāi)始。

TTS WTS(X) TTS RTS(X):事務(wù)更新 X,WTS(X) = TTS。

這里之所以要求 TTS RTS(X),是為了防止如下情況:讀請(qǐng)求的時(shí)間戳為 rts,已經(jīng)讀過(guò) X,時(shí)間戳設(shè)為 RTS(X)=rts,如果新事務(wù)的 TTS   RTS(X),并且更新成功,則 rts 讀請(qǐng)求再來(lái)讀一次就看到新的更改了,違反了 repeatable  read,因此這是為了避免讀寫(xiě)沖突。記錄上存儲(chǔ)了最后的讀寫(xiě)時(shí)間,可以保證 conflict serializable

這種方式也能避免 write skew,例如:初始狀態(tài),X 和 Y 兩條記錄,X=-3,Y=5,X+Y   0,RTS(X)=RTS(Y)=WTS(X)=WTS(Y)=0。事務(wù) T1 的時(shí)間戳為 TTS1=1,事務(wù) T2 的時(shí)間戳 TTS2=2。

它缺陷包括:

長(zhǎng)事務(wù)容易餓死,因?yàn)殚L(zhǎng)事務(wù)的 timestamp 偏小,大概率會(huì)在執(zhí)行一段時(shí)間后讀到更新的數(shù)據(jù),導(dǎo)致 abort。

讀操作也會(huì)產(chǎn)生寫(xiě)(寫(xiě) RTS)。

4. 基于 Validation(OCC)的并發(fā)控制

執(zhí)行過(guò)程中,每個(gè)事務(wù)維護(hù)自己的寫(xiě)操作 (Basic  T/ O 在事務(wù)執(zhí)行過(guò)程中寫(xiě)就將數(shù)據(jù)寫(xiě)入 DB) 和相應(yīng)的 RTS/WTS,提交時(shí)判斷自己的更改是否和數(shù)據(jù)庫(kù)中已存在的數(shù)據(jù)沖突,如果不沖突才寫(xiě)入 DB。OCC 分為三個(gè)階段:

Read Write Phase:即讀寫(xiě)階段,事務(wù)維護(hù)讀的結(jié)果和即將提交的更改,以及寫(xiě)入記錄的 RTS 和 WTS。

Validation Phase:檢查事務(wù)是否與數(shù)據(jù)庫(kù)中的數(shù)據(jù)沖突。

Write Phase:不沖突就寫(xiě)入,沖突就 abort,restart。

Read Write Phase 結(jié)束,進(jìn)入 Validation Phase 相當(dāng)于事務(wù)準(zhǔn)備完成,進(jìn)入提交階段了,進(jìn)入 Validation  Phase 的時(shí)間被選做記錄行的時(shí)間戳,來(lái)定序。不用事務(wù)開(kāi)始時(shí)間是因?yàn)椋菏聞?wù)執(zhí)行時(shí)間可能較長(zhǎng),導(dǎo)致后開(kāi)始的事務(wù)可能先提交,這會(huì)加大事務(wù)沖突的概率,較小時(shí)間戳的事務(wù)后寫(xiě)入數(shù)據(jù)庫(kù),肯定會(huì) abort。

Validation 過(guò)程

假設(shè)當(dāng)前只有兩個(gè)事務(wù) T1 和 T2,并修改了相同數(shù)據(jù)行,T1 的時(shí)間戳 T2 的時(shí)間戳(即 validation 順序:T1  T2,對(duì)用戶(hù)而言,T1 先發(fā)生于 T2),則有如下情況:

(1)T1 在 validate 階段,T2 還在 Read Write Phase。此時(shí)只要 T1 和 T2 已經(jīng)發(fā)生的讀寫(xiě)沒(méi)有沖突,就可以提交。

如果 WS(T1) cap; (RS(T2) cup; WS(T2)) = empty;,說(shuō)明 T2 和 T1 寫(xiě)的記錄無(wú)沖突,validation 通過(guò),可以寫(xiě)入。

否則,T2 與 T1 之間存在讀寫(xiě)沖突或?qū)憣?xiě)沖突,T1 需要回滾。讀寫(xiě)沖突:T2 讀到了 T1 寫(xiě)之前的版本,T1 提交后,它可能讀到 T1 寫(xiě)的版本,不可重復(fù)讀。寫(xiě)寫(xiě)沖突:T2 有可能在舊版本基礎(chǔ)上更新,再次寫(xiě)入,造成 T1 的更新丟失。

(2)T1 完成 validate 階段,進(jìn)入 write 階段直到提交完成,這已經(jīng)是不可逆的了。T2 在 T1 進(jìn)入 write  phase 之前的讀寫(xiě),肯定和 T1 的操作不沖突(因?yàn)?T1  validation 通過(guò)了)。T2 之后繼續(xù)的讀寫(xiě)操作,有可能沖突與 T1 要提交的操作,因此 T2 進(jìn)入 validate 階段:

如果 WS(T1) cap; RS(T2)=   empty;,說(shuō)明 T2 沒(méi)讀到 T1 寫(xiě)的記錄,validation 通過(guò),T2 可以寫(xiě)入。(為什么不驗(yàn)證 WS(T2)了呢?WS(T1)已經(jīng)提交了,且它的時(shí)間戳小于 WS(T2),WS(T2)里之前的一部分肯定沒(méi)有沖突,之后的一部分,因?yàn)闆](méi)有讀過(guò) T1 的寫(xiě)入的對(duì)象,寫(xiě)進(jìn)去也沒(méi)問(wèn)題,不會(huì)覆蓋 WS(T1)的寫(xiě))

否則,T2 與 T1 之間存在讀寫(xiě)沖突和寫(xiě)寫(xiě)沖突,T2 需要回滾。讀寫(xiě)沖突:T2 讀到了 T1 寫(xiě)之前的版本,T1 提交后,它可能讀到 T1 寫(xiě)的版本,不可重復(fù)讀。寫(xiě)寫(xiě)沖突:T2 有可能在舊版本基礎(chǔ)上更新,再次寫(xiě)入,造成 T1 的更新丟失。

5. 基于 MVCC 的并發(fā)控制

數(shù)據(jù)庫(kù)維護(hù)了一條記錄的多個(gè)物理版本。事務(wù)寫(xiě)入時(shí),創(chuàng)建寫(xiě)入數(shù)據(jù)的新版本,讀請(qǐng)求依據(jù)事務(wù) / 語(yǔ)句開(kāi)始時(shí)的快照信息,獲取當(dāng)時(shí)已經(jīng)存在的最新版本數(shù)據(jù)。它帶來(lái)的最直接的好處是:寫(xiě)不阻塞讀,讀也不阻塞寫(xiě),讀請(qǐng)求永遠(yuǎn)不會(huì)因此沖突失敗 (例如單版本 T /O) 或者等待(例如單版本 2PL)。對(duì)數(shù)據(jù)庫(kù)請(qǐng)求來(lái)說(shuō),讀請(qǐng)求往往多于寫(xiě)請(qǐng)求。主流的數(shù)據(jù)庫(kù)幾乎都采用了這項(xiàng)優(yōu)化技術(shù)。

MVCC 是讀和寫(xiě)請(qǐng)求的優(yōu)化技術(shù),沒(méi)有完全解決數(shù)據(jù)庫(kù)并發(fā)問(wèn)題,它需要與前述的幾種并發(fā)控制技術(shù)組合,才能提供完整的并發(fā)控制能力。常見(jiàn)的并發(fā)控制技術(shù)種類(lèi)包括:MV-2PL,MV-T/ O 和 MV-OCC,它們的特點(diǎn)如下表:

MVCC 還有兩個(gè)關(guān)鍵點(diǎn)需要考慮:多版本數(shù)據(jù)的存儲(chǔ)和多余多版本數(shù)據(jù)的回收。

多版本數(shù)據(jù)存儲(chǔ)方式,大致可以分為兩類(lèi):(1)Append  only 的方式,新舊版本存儲(chǔ)在同一個(gè)表空間,例如基于 LSM-Tree 的存儲(chǔ)引擎。(2)主表空間記錄最新版本數(shù)據(jù),前鏡像記錄在其它表空間或數(shù)據(jù)段,例如 InnoDB 的多版本信息記錄在 undo  log。多版本數(shù)據(jù)回收又稱(chēng)為垃圾回收(GC),那些沒(méi)有機(jī)會(huì)再被任何讀請(qǐng)求獲取的舊版本記錄,應(yīng)該被及時(shí)刪除。

依據(jù)沖突處理的時(shí)機(jī) (樂(lè)觀程度),依次介紹了基于鎖(在事務(wù)開(kāi)始前預(yù)防沖突)、基于 T /O(在事務(wù)執(zhí)行中判斷沖突) 和基于 Validation(在事務(wù)提交時(shí)驗(yàn)證沖突)的事務(wù)并發(fā)控制機(jī)制。不同的實(shí)現(xiàn)適用于不同的 workload,并發(fā)沖突小的 workload,當(dāng)然適合更樂(lè)觀的并發(fā)控制方式。而 MVCC 可以解決只讀事務(wù)和讀寫(xiě)事務(wù)之間相互阻塞的問(wèn)題,提高了事務(wù)的并發(fā)讀,被大多數(shù)主流數(shù)據(jù)庫(kù)系統(tǒng)采用。

看完上述內(nèi)容,你們掌握數(shù)據(jù)庫(kù)并發(fā)控制的作用及示例分析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道,感謝各位的閱讀!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-17發(fā)表,共計(jì)7326字。
轉(zhuǎn)載說(shuō)明:除特殊說(shuō)明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請(qǐng)注明出處。
評(píng)論(沒(méi)有評(píng)論)
主站蜘蛛池模板: 柘荣县| 通江县| 棋牌| 临沧市| 巨野县| 工布江达县| 南靖县| 汉川市| 枞阳县| 磴口县| 阿拉尔市| 界首市| 宁海县| 柞水县| 太白县| 桐庐县| 吴忠市| 绍兴县| 漾濞| 达州市| 军事| 霍山县| 丰顺县| 阿瓦提县| 肃南| 郎溪县| 栾川县| 昭通市| 合水县| 岫岩| 娱乐| 天水市| 焉耆| 霍山县| 南京市| 河池市| 公安县| 旌德县| 江门市| 赤峰市| 吴忠市|