PG mvcc可見性判斷

1、知識準備

1)Tuple格式頭HeapTupleHeaderData

<code>typedef struct HeapTupleFields

{

TransactionId t_xmin;   /* inserting xact ID */

TransactionId t_xmax;   /* deleting or locking xact ID */

union

{

CommandId t_cid;   /* inserting or deleting command ID, or both */

TransactionId t_xvac; /* VACUUM FULL xact ID */

}t_field3;

}HeapTupleFields;/<code>

其中:

t_xmin:存儲的是產生這個元組的事務ID,可能是insert或者update語句

t_xmax:存儲的是刪除或者鎖定這個元組的事務ID

t_cid :包含cmin和cmax兩個字段,分別存儲創建這個元組的Command ID和刪除這個元組的Command ID

t_xvac:存儲的是VACUUM FULL 命令的事務ID

PostgreSQL主要就是通過t_xmin,t_xmax,cmin和cmax,ctid,t_infomask來唯一定義一個元組(t_xmin,t_xmax,cmin和cmax,ctid實際上也是一個表的隱藏的標記字段)。

2)Clog

PostgreSQL 在 CLOG 中維護事務的狀態,持久化存儲在 pg_xact 目錄下,為了訪問高效,會在內存中維護一塊共享內存用於緩存 CLOG 的內容。

PG定義有四種事務狀態:

<code>#define TRANSACTION_STATUS_IN_PROGRESS 0x00

#define TRANSACTION_STATUS_COMMITTED 0x01

#define TRANSACTION_STATUS_ABORTED 0x02

#define TRANSACTION_STATUS_SUB_COMMITTED 0x03/<code>

Clog文件以頁為單位。數組下標是事務ID,參考TransactionIdGetStatus這個函數。數組內容是事務狀態,每個事務狀態佔用2bit即可。一個頁面8K,可以存儲8K*8/2=32K個事務狀態。Clog buffer大小為Min(128, Max(4, NBuffers / 512)),初始化函數為CLOGShmemInit。啟動時會從pg_xact讀取事務狀態加載到內存。系統運行過程中,vacuum會定時將不再使用的clog文件清理。

3)Hint

在進行可見性判斷時,需要獲取事務的狀態,即元組中 t_xmin 和 t_xmax 的狀態,這些事務狀態保存在 CLOG 中,為加速獲取事務狀態的過程,PostgreSQL 引入了 Hint Bits。

所有 Hint Bits,就是把事務狀態直接記錄在元組頭中(HeapTupleHeaderData),避免頻繁訪問 CLOG,元組頭中對應的標識位如下:tuple->t_infomask

<code>#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */

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

#define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)

#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */

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

#define HEAP_XMAX_IS_MULTI 0x1000 /* t_xmax is a MultiXactId *//<code>

PostgreSQL 並不會在事務提交或者回滾時主動更新元組上的 Hint Bits,而是等到訪問該元組並進行可見性判斷時,如果發現 Hint Bits 沒有設置,則從 CLOG 中讀取並設置,否則直接讀取 Hint Bits 的值。判斷可見性過程中設置 Hint Bits 的函數入口為 SetHintBits。這裡的訪問可能是 VACUUM,DML 或者 SELECT。

因此,Hint Bits 可以理解為是事務狀態在元組頭上的一份緩存。

4)Hint與日誌

在開啟 checksum 或者 GUC 參數 wal_log_hints 為 true 的情況下,如果 checkpoint 後第一次使頁面 dirty 的操作是更新 Hint Bits,則會產生一條 WAL 日誌,將當前頁面寫入 WAL 日誌中(即 Full Page Image),避免產生部分寫,導致數據 checksum 異常。注意,以上寫 Full Page Image 日誌的行為與是否開啟 full_page_writes 沒有關係。因此,在開啟 checksum 或者 GUC 參數 wal_log_hints 為 true 時,即便執行 SELECT,也可能更改頁面的 Hint Bits,從而導致產生 WAL 日誌,這會在一定程度上增加 WAL 日誌佔用的存儲空間。

2、快照判斷


PG mvcc可見性判斷


判斷一個事務是否在快照,即針對這個快照是否還在in progress:

1)大於等於snap->xmax:未來事務,不可見

2)小於snap->xmin:已結束事務,可見

3)[snap->xmin,snap->xmax):查看CLOG。Commit狀態:可見;in progress和abort狀態:不可見

3、MVCC判斷可見性

PG mvcc可見性判斷


可見性判斷規則可歸納為:

<code>/* t_xmin status = ABORTED */

Rule 1: IF t_xmin status is 'ABORTED' THEN

            RETURN 'Invisible'

        END IF

            

/* 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

/* 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/<code>

4、參考

https://yq.aliyun.com/articles/675939

http://blog.itpub.net/6906/viewspace-2562652/


分享到:


相關文章: