PostgreSQL技術(shù)大講堂 - 第20講:事務(wù)概述與隔離級(jí)別
PostgreSQL從小白到專家,是從入門逐漸能力提升的一個(gè)系列教程,內(nèi)容包括對(duì)PG基礎(chǔ)的認(rèn)知、包括安裝使用、包括角色權(quán)限、包括維護(hù)管理、、等內(nèi)容,希望對(duì)熱愛PG、學(xué)習(xí)PG的同學(xué)們有幫助,歡迎持續(xù)關(guān)注CUUG PG技術(shù)大講堂。
第20講:事務(wù)概述與隔離級(jí)別
內(nèi)容1:ACID四大特性
內(nèi)容2:PostgreSQL事務(wù)隔離級(jí)別
內(nèi)容3:MVCC介紹
內(nèi)容4:Clog與事務(wù)狀態(tài)
內(nèi)容5:事務(wù)快照
內(nèi)容6:可重復(fù)讀隔離級(jí)別特點(diǎn)
內(nèi)容7:讀提交隔離級(jí)別特點(diǎn)
內(nèi)容8:可串行化隔離級(jí)別特點(diǎn)
ACID概述
· ACID四大特性:
--> Atomicity(原子性):一個(gè)事務(wù)(transaction)中的所有操作,要么全部完成,要么全部不完成,不會(huì)結(jié)束在中間某個(gè)環(huán)節(jié)。
--> Consistency(一致性):在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫(kù)的完整性沒有被破壞。這表示寫入的數(shù)據(jù)必須完全符合所有的預(yù)設(shè)規(guī)則,這包含數(shù)據(jù)的精確度、串聯(lián)性以及后續(xù)數(shù)據(jù)庫(kù)可以自發(fā)性地完成預(yù)定的工作。
--> Isolation(隔離性):數(shù)據(jù)庫(kù)允許多個(gè)并發(fā)事務(wù)同時(shí)對(duì)其數(shù)據(jù)進(jìn)行讀寫和修改的能力,隔離性可以防止多個(gè)事務(wù)并發(fā)執(zhí)行時(shí)由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。
--> Durability(持久性):事務(wù)處理結(jié)束后,對(duì)數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會(huì)丟失。

PostgreSQL支持的事務(wù)隔離級(jí)別
·?下表描述了PostgreSQL實(shí)現(xiàn)的事務(wù)隔離級(jí)別
MVCC概述
· 事務(wù)id(txid)
并發(fā)控制是一種在數(shù)據(jù)庫(kù)中并發(fā)運(yùn)行多個(gè)事務(wù)時(shí)保持一致性和隔離性的機(jī)制,這是ACID的兩個(gè)屬性。
并發(fā)控制技術(shù):
--> 多版本并發(fā)控制(MVCC)
--> 嚴(yán)格的兩階段鎖(S2PL)
--> 樂觀并發(fā)控制(OCC)
· MVCC特點(diǎn)
每次寫操作都會(huì)創(chuàng)建數(shù)據(jù)項(xiàng)的新版本,同時(shí)保留舊版本。當(dāng)事務(wù)讀取一個(gè)數(shù)據(jù)項(xiàng)時(shí),系統(tǒng)會(huì)選擇其中一個(gè)版本以確保單個(gè)事務(wù)的隔離。MVCC的主要優(yōu)點(diǎn)是“讀不阻止寫,寫不阻止讀,相反,例如,基于S2PL的系統(tǒng)必須在寫卡器寫入項(xiàng)時(shí)阻止讀卡器,因?yàn)閷懣ㄆ鳙@取項(xiàng)的獨(dú)占鎖。PostgreSQL和一些rdbms使用MVCC的一個(gè)變體,稱為快照隔離(Snapshot Isolation,SI)。
MVCC實(shí)現(xiàn)對(duì)比
· 事務(wù)id(txid)
PostgreSQL通過應(yīng)用可見性檢查規(guī)則來選擇項(xiàng)目的適當(dāng)版本
由于PostgreSQL數(shù)據(jù)塊中包含了未刪除和已刪除的行的數(shù)據(jù),所以在讀取數(shù)據(jù)塊中行的時(shí)候,需要一套規(guī)則來判斷哪些行能夠被哪些事務(wù)所看得見,我們成為行可見性規(guī)則
Oracle使用回滾段來選擇項(xiàng)目的適當(dāng)版本
Oracle專門創(chuàng)建了一個(gè)回滾表空間,用來存放修改前的行的數(shù)據(jù),而表的數(shù)據(jù)塊中沒有包含刪除行的數(shù)據(jù),所以不需要行可見性規(guī)則來判斷。
事務(wù)狀態(tài)
· Transaction Status
四種事務(wù)狀態(tài):
--> IN_PROGRESS
--> COMMITTED
--> ABORTED
--> SUB_COMMITTED
Commit Log
· Clog 工作原理
事務(wù)快照
· 內(nèi)置函數(shù)txid_current_snapshot及其文本表示格式
testdb=# SELECT txid_current_snapshot();
txid_current_snapshot
-----------------------
100:104:100,102
(1 row)
· txid_current_snapshot的文本表示為“xmin:xmax:xip_list”,組件描述如下
Xmin:最早仍在活動(dòng)的txid。所有以前的事務(wù)要么提交并可見,要么回滾并停止。
Xmax:第一個(gè)尚未分配的txid。截至快照時(shí),所有大于或等于此值的txid尚未啟動(dòng),因此不可見。
xip_list:快照時(shí)的活動(dòng)txid。該列表僅包含xmin和xmax之間的活動(dòng)txid。
例如,在快照'100:104:100,102'中,xmin是'100',xmax是'104',xip_list是'100,102'。
· Examples of transaction snapshot representation
事務(wù)管理器
· 不同隔離級(jí)別的事務(wù)快照狀態(tài)
并發(fā)UPDATE時(shí)
防止更新的數(shù)據(jù)丟失
· 并發(fā)UPDATE操作,隔離級(jí)別不同如何保護(hù)已修改的數(shù)據(jù)不丟失
1)如果A事務(wù)回滾,則b事務(wù)能夠更新成功
2)B事務(wù)如果查詢了表,則再次更新時(shí)失敗,如果沒有,則會(huì)更新成功
防止更新的數(shù)據(jù)丟失
· 讀提交事務(wù)隔離級(jí)別(事務(wù)A和B同時(shí)修改同一行)
· 可重復(fù)讀事務(wù)隔離級(jí)別(事務(wù)A和B同時(shí)修改同一行)
· 可重復(fù)讀事務(wù)隔離級(jí)別(事務(wù)B在提交前執(zhí)行了查詢)
· 可重復(fù)讀事務(wù)隔離級(jí)別(事務(wù)B在提交前沒有執(zhí)行查詢)

可串行化快照隔離
· SSI(可串行化快照隔離)實(shí)施的基本策略
寫入傾斜計(jì)劃及其優(yōu)先級(jí)圖
· 在PostgreSQL中實(shí)現(xiàn)SSI
SIREAD locks:SIREAD鎖在內(nèi)部稱為謂詞鎖,三個(gè)部分組成,由一對(duì)對(duì)象和(虛擬)txid 組成。
rw-conflicts:rw-conflicts是SIREAD鎖的三個(gè)組成部分中的一個(gè)和讀寫SIREAD鎖的兩個(gè)txid
· SSI 怎樣造成的
事務(wù)提交失敗的原因是要保護(hù)事務(wù)A修改的結(jié)果,因?yàn)槭聞?wù)B是在可串行化事務(wù)隔離級(jí)別,所以無法看到事務(wù)A修改后的結(jié)果
· 其它造成的場(chǎng)景
注意事務(wù)提交的不同順序
· 假陽(yáng)性可串行化快照隔離異常
兩個(gè)事務(wù)分別查詢和更新各自的行,所以不會(huì)影響,都能夠提交成功。
· 假陽(yáng)性可串行化快照隔離異常(1) – Using sequential scan
表沒有索引,導(dǎo)致順序掃描,兩個(gè)事務(wù)操作時(shí)發(fā)生交叉訪問同一個(gè)塊
· 假陽(yáng)性可串行化快照隔離異常(2) – Index scan using the same index page
如果表比較小,導(dǎo)致root和leaf索引塊同屬于一個(gè)塊,兩個(gè)事務(wù)也發(fā)生交叉訪問同一個(gè)索引塊
· 假陽(yáng)性可串行化快照隔離異常(3) – Index scan using the difference index page
插入新數(shù)據(jù),導(dǎo)致root和leaf索引塊不屬于一個(gè)塊,不會(huì)造成交叉訪問


以上就是 第20講- 事務(wù)與隔離級(jí)別 的內(nèi)容,歡迎一起探討交流,往期視頻,聯(lián)系cuug