最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

PostgreSQL技術大講堂 - 第21講:行可見性規(guī)則

2023-07-05 17:10 作者:北京CUUG  | 我要投稿



PostgreSQL從小白到專家,是從入門逐漸能力提升的一個系列教程,內(nèi)容包括對PG基礎的認知、包括安裝使用、包括角色權限、包括維護管理、、等內(nèi)容,希望對熱愛PG、學習PG的同學們有幫助,歡迎持續(xù)關注CUUG PG技術大講堂。

第21講:行可見性規(guī)則

內(nèi)容1:PostgreSQL事務id介紹

內(nèi)容2:PostgreSQL DML操作原理

內(nèi)容3:事務快照在可見性規(guī)則中的作用

內(nèi)容4:T_xmin狀態(tài)對于可見性規(guī)則判斷的重要度

內(nèi)容5:常見的行可見性規(guī)則的介紹

內(nèi)容6:實現(xiàn)閃回功能


TXID介紹

· 事務id(txid)

當一個事務開始時,PostgreSQL中的事務管理系統(tǒng)會為該事務分配一個唯一標識符,即事務ID(txid).PostgreSQL中的txid被定義為一個32位的無符號整數(shù),也就是說,它能記錄大約42億個事務。通常txid對我們是透明的,但是我們可以利用PostgreSQL內(nèi)部的函數(shù)來獲取當前事務的txid。

事務ID用來標識一個事務的先后順序,該順序決定了鎖申請的優(yōu)先權,已經(jīng)訪問一張表時對行的可見性規(guī)則判斷。

testdb=# SELECT txid_current();

txid_current

--------------

100

(1 row)


Tuples Structure

· 元組(行)結構

t_xmin保存插入此元組的事務的txid,它的狀態(tài)是行可見性判斷關鍵的依據(jù)。

t_xmax保存刪除或更新此元組的事務的txid。如果此元組未被刪除或更新,則t_xmax設置為0,這意味著無效,它的狀態(tài)也是行可見性判斷關鍵的依據(jù)。


DML操作原理

· Insertion

· Deletion

· Update

執(zhí)行第一個更新命令時,通過將txid 100設置為t_xmax,邏輯上刪除Tuple_1,然后插入Tuple_2。然后,將元組1的t_ctid重寫為指向元組2。

當執(zhí)行第二個UPDATE命令時,與第一個UPDATE命令一樣,Tuple_2在邏輯上被刪除,Tuple_3被插入。


事務狀態(tài)

· 四種事務狀態(tài)

IN_PROGRESS

COMMITTED

ABORTED

SUB_COMMITTED


Commit Log

· 事務狀態(tài)記錄方式

事務快照

· 事務快照概述

事務快照是一個數(shù)據(jù)集,用于存儲有關單個事務在某個時間點上是否所有事務都處于活動狀態(tài)的信息。在這里,活動事務表示它正在進行或尚未啟動。txid_current_snapshot的文本表示為“xmin:xmax:xip_list”,組件描述如下:

Xmin:最早仍在活動的txid。所有以前的事務要么提交并可見,要么回滾并停止。

Xmax:第一個尚未分配的txid。截至快照時,所有大于或等于此值的txid尚未啟動,此不可見。

xip_list:快照時的活動txid。該列表僅包含xmin和xmax之間的活動txid。

testdb=# SELECT txid_current_snapshot();

txid_current_snapshot

-----------------------

100:104:100,102

(1 row)

例如,在快照'100:104:100,102'中,xmin是'100',xmax是'104',xip_list是'100,102'。


可見性規(guī)則世界觀

· 事務快照在可見性規(guī)則中的意義

富有哲理性的判斷規(guī)則:過去發(fā)生過的為可見,將來未發(fā)生的為不可見。


行可見性判斷重要因素

· 可見性判斷的重要因素

可見性檢查規(guī)則是一組規(guī)則,關鍵的判斷因素有:t_xmin、t_xmax、clog和獲取的事務快照確定每個元組是否可見。

T_xmin的三種狀態(tài)ABORTED、IN_PROGRESS、COMMITTED是判斷的第一前提條件。


ABORTED狀態(tài)

· t_xmin =ABORTED

t_xmin =ABORTED,則判斷此行不可見

/* t_xmin status = ABORTED */

Rule 1: IF t_xmin status is 'ABORTED' THEN

RETURN 'Invisible'

END IF


IN_PROGRESS狀態(tài)

· t_xmin=IN_PROGRESS

t_xmin=IN_PROGRESS,當前事務可見,其它事務不可見

/* t_xmin status = IN_PROGRESS */

IF t_xmin status is 'IN_PROGRESS' THEN

IF t_xmin = current_txid THEN

Rule 2: IF t_xmax = INVALID THEN

RETURN 'Visible'

Rule 3: ELSE /* this tuple has been deleted or updated by the current transaction itself. */

RETURN 'Invisible'

END IF

Rule 4: ELSE /* t_xmin ≠ current_txid */

RETURN 'Invisible'

END IF

END IF


COMMITTED狀態(tài)

· t_xmin=COMMITTED

t_xmin=COMMITTED,此狀態(tài)判斷時還得看t_xmax的值,如果t_xmax的值為0,則此行可見;如果不為0,那么判斷時還得看t_xmax的狀態(tài)是當前事務還是非當前事務,判斷規(guī)則就比較復雜。

/* t_xmin status = COMMITTED */

IF t_xmin status is 'COMMITTED' THEN

Rule 5: IF t_xmin is active in the obtained transaction snapshot THEN

RETURN 'Invisible'

Rule 6: ELSE IF t_xmax = INVALID OR status of t_xmax is 'ABORTED' THEN

RETURN 'Visible'

ELSE IF t_xmax status is 'IN_PROGRESS' THEN

Rule 7: IF t_xmax = current_txid THEN

RETURN 'Invisible'

Rule 8: ELSE /* t_xmax ≠ current_txid */

RETURN 'Visible'

END IF

ELSE IF t_xmax status is 'COMMITTED' THEN

Rule 9: IF t_xmax is active in the obtained transaction snapshot THEN

RETURN 'Visible'

Rule 10: ELSE

RETURN 'Invisible'

END IF

END IF

END IF


可見性判斷概述

· 可見性判斷示例


R6判斷規(guī)則

· T3 時根據(jù)規(guī)則6進行判斷

Rule6(Tuple_1)?Status(t_xmin:199) = COMMITTED ∧ t_xmax = INVALID ?Visible

T_xmin=commit,并且t_xman=0,該行對于所有的事務均可見


R7與R2判斷規(guī)則

· T5時事務ID為200的根據(jù)規(guī)則7、2進行判斷

Rule7(Tuple_1): Status(t_xmin:199) = COMMITTED ∧ Status(t_xmax:200) = IN_PROGRESS ∧ t_xmax:200 = current_txid:200 ? Invisible

Rule2(Tuple_2): Status(t_xmin:200) = IN_PROGRESS ∧ t_xmin:200 = current_txid:200 ∧ t_xmax = INVAILD ? Visible

此時塊中包含兩行數(shù)據(jù),對于事務id=200來說,它的判斷規(guī)則是:

第一行數(shù)據(jù)根據(jù)規(guī)則7判斷,t_xmin=commit,同時(t_xmax=200)= IN_PROGRESS,并且t_xmax:200為當前事務id,則第一行判斷為不可見。

第二行根據(jù)規(guī)則2判斷, t_xmin=commit,同時(t_xmax=200)為當前事務id,并且t_xmax為無效,則該行可見。

testdb=# -- txid 200

testdb=# SELECT * FROM tbl;

name

------

Hyde


R8與R4判斷規(guī)則

· T5時事務ID為201的根據(jù)規(guī)則8、4進行判斷

Rule8(Tuple_1): Status(t_xmin:199) = COMMITTED ∧ Status(t_xmax:200) = IN_PROGRESS ∧ t_xmax:200 ≠ current_txid:201 ? Visible

Rule4(Tuple_2): Status(t_xmin:200) = IN_PROGRESS ∧ t_xmin:200 ≠ current_txid:201 ? Invisible

此時塊中包含兩行數(shù)據(jù),對于事務id=201來說,它的判斷規(guī)則是:

第一行數(shù)據(jù)根據(jù)規(guī)則8判斷,t_xmin=commit,同時(t_xmax=200)= IN_PROGRESS,并且t_xmax:200不是當前事務id,則第一行判斷為可見。

第二行根據(jù)規(guī)則2判斷, (t_xmax=200)狀態(tài)為IN_PROGRESS,同時t_xmin不是當前事務id,則該行不可見。

testdb=# -- txid 201

testdb=# SELECT * FROM tbl;

name

--------

Jekyll


R10與R6判斷規(guī)則

· T7時事務ID為201的根據(jù)規(guī)則10、6進行判斷(READ COMMITED)

Rule10(Tuple_1): Status(t_xmin:199) = COMMITTED ∧ Status(t_xmax:200) = COMMITTED ∧ Snapshot(t_xmax:200) ≠ active ? Invisible

Rule6(Tuple_2): Status(t_xmin:200) = COMMITTED ∧ t_xmax = INVALID ? Visible

T7時事務id為200的提交了事務,對于事務id=201來說,它的判斷規(guī)則是:

第一行根據(jù)規(guī)則10判斷,t_xmin=commit,同時(t_xmax=200)= COMMITTED ,并且Snapshot(t_xmax:200) 狀態(tài)為非活動,則第一行判斷為不可見。

第二行根據(jù)規(guī)則6判斷, (t_xmax=200)狀態(tài)為COMMITTED ,同時t_xmax為無效,則該行可見。

testdb=# -- txid 201 (READ COMMITTED)

testdb=# SELECT * FROM tbl;

name

------

Hyde


R9與R5判斷規(guī)則

· T7時事務ID為201的根據(jù)規(guī)則9、5進行判斷(REPEATABLE READ)

Rule9(Tuple_1): Status(t_xmin:199) = COMMITTED ∧ Status(t_xmax:200) = COMMITTED ∧ Snapshot(t_xmax:200) = active ? Visible

Rule5(Tuple_2): Status(t_xmin:200) = COMMITTED ∧ Snapshot(t_xmin:200) = active ? Invisible

如果事務的隔離級別是可重復讀,那么其判斷規(guī)則就會發(fā)生變化,T7時事務id為200的提交了事務,對于事務id=201來說,它的判斷規(guī)則是:

第一行根據(jù)規(guī)則9判斷,t_xmin=commit,同時(t_xmax=200)= COMMITTED ,并且Snapshot(t_xmax:200) 狀態(tài)為活動,則第一行判斷為可見。

第二行根據(jù)規(guī)則5判斷, t_xmax=200狀態(tài)為COMMITTED , Snapshot(t_xmin:200) 為活動,則該行不可見,通過該規(guī)則,不會導致幻讀發(fā)生。

testdb=# -- txid 201 (REPEATABLE READ)

testdb=# SELECT * FROM tbl;

name

--------

Jekyll


提高判斷效率

· Hint Bits

由于進行行可見性判斷時都要查看存儲在clog中t_xmin和t_xmax的狀態(tài),為了解決對clog頻繁訪問這個問題,PostgreSQL使用了提示位,如下所示:

#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */

#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */

#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */

#define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */


實現(xiàn)閃回功能

PostgreSQL由于數(shù)據(jù)的更新時新舊數(shù)據(jù)都保留在數(shù)據(jù)塊中,那么如果要實現(xiàn)像Oracle一樣的閃回查詢功能應該是可以實現(xiàn)的,只要在判斷時先判斷該查詢是否是閃回查詢,然后再根據(jù)一個針對閃回查詢的可見性規(guī)則判斷就可以實現(xiàn)。

如果實現(xiàn)閃回查詢,那么涉及到Vacuum操作時需要考慮更多的因素,需要有一個參數(shù)來設置塊中被刪除的行保留的時間長度。



以上就是【PostgreSQL從小白到專家】第21講 - 行可見性規(guī)則 的內(nèi)容,歡迎一起探討交流,往期視頻及文檔,聯(lián)系CUUG

PostgreSQL技術大講堂 - 第21講:行可見性規(guī)則的評論 (共 條)

分享到微博請遵守國家法律
阳山县| 雅安市| 连州市| 陆河县| 金寨县| 西充县| 托克逊县| 甘洛县| 女性| 琼海市| 许昌市| 凤冈县| 习水县| 孝义市| 连江县| 普陀区| 北宁市| 内黄县| 台州市| 永兴县| 宝丰县| 满洲里市| 禄劝| 陇南市| 巍山| 四子王旗| 蒲江县| 株洲县| 阳谷县| 分宜县| 安顺市| 盘山县| 拉萨市| 鄂托克前旗| 库尔勒市| 东乡县| 哈巴河县| 连州市| 淮北市| 德格县| 永宁县|