PostgreSQL的元組 頁面結構及索引查詢原理

2021-10-01 18:48:12 字數 3025 閱讀 8611

我們知道postgresql資料庫通過資料多版本實現mvcc,pg又沒有undo段,老版本的資料元組直接存放在資料頁面中,這樣帶來的問題就是舊元組需要不斷地進行清理以釋放空間,這也是資料庫膨脹的根本原因。本文簡單介紹一下postgresql資料庫的元組、頁面的結構以及索引查詢流程。

元組結構

元組,也叫tuple,這個叫法是很學術的叫法,但是現在資料庫中一般叫行或者記錄。下面是元組的結構:

typedef struct heaptuplefields

t_field3;

} heaptuplefields;

struct heaptupleheaderdata

t_choice;

itempointerdata t_ctid; /* current tid of this or newer tuple (or a

* speculative insertion token) */

/* fields below here must match minimaltupledata! */

#define fieldno_heaptupleheaderdata_infomask2 2

uint16 t_infomask2; /* number of attributes + various flags */

#define fieldno_heaptupleheaderdata_infomask 3

uint16 t_infomask; /* various flag bits, see below */

#define fieldno_heaptupleheaderdata_hoff 4

uint8 t_hoff; /* sizeof header incl. bitmap, padding */

/* ^ - 23 bytes - ^ */

#define fieldno_heaptupleheaderdata_bits 5

bits8 t_bits[flexible_array_member]; /* bitmap of nulls */

/* more data follows at end of struct */

};

t_xmin:代表插入此元組的事務xid;

t_xmax:代表更新或者刪除此元組的事務xid,如果該元組插入後未進行更新或者刪除,t_xmax=0;

t_cid:command id,代表在當前事務中,已經執行過多少條sql,例如執行第一條sql時cid=0,執行第二條sql時cid=1;

t_ctid:儲存著指向自身或者新元組的元組標識(tid),由兩個數字組成,第乙個數字代表物理塊號,或者叫頁面號,第二個數字代表元組號。在元組更新後tid指向新版本的元組,否則指向自己,這樣其實就形成了新舊元組之間的「元組鏈」,這個鏈在元組查詢和定位上起著重要作用。

了解了元組結構,再簡單了解下元組更新和刪除過程。

更新過程

上圖中左邊是一條新插入的元組,可以看到元組是xid=100的事務插入的,沒有進行更新,所以t_xmax=0,同時t_ctid指向自己,0號頁面的第一號元組。右圖是發生xid=101的事務更新該元組後的狀態,更新在pg裡相當於插入一條新元組,原來的元組的t_xmax變為了更新這條事務的xid=101,同時t_ctid指標指向了新插入的元組(0,2),0號頁面第二號元組,第二號元組的t_xmin=101(插入該元組的xid),t_ctid=(0,2),沒有發生更新,指向自己。

刪除過程

上圖代表該元組被xid=102的事務刪除,將t_xmax設定為刪除事務的xid,t_ctid指向自己。

頁面結構

下面再來看看頁面的結構

從上圖可以看到,頁面包括三種型別的資料

1.header data:資料頭是page生成的時候隨之產生的,由pageheaderdata定義結構,24個位元組長,包含了page的相關資訊,下面是資料結構:

typedef struct pageheaderdata

pageheaderdata;

pd_lsn: 儲存最近改變該頁面的xlog位置。

pd_checksum:儲存頁面校驗和。

pd_lower,pd_upper:pd_lower指向行指標(line pointer)的尾部,pd_upper指向最後那個元組。

pd_special: 索引頁面中使用,它指向特殊空間的開頭。

2.line pointer:行指標,四位元組,每一條元組會有乙個行指標指向真實元組位置。

3.heap tuple:存放真實的元組資料,注意元組是從頁面的尾部向前堆積的,元組和行指標之間的是資料頁的空閒空間。

索引查詢

看了頁面和元組結構,再看看索引的結構。

以上圖為例,索引的資料報含兩部分(key=***,tid=(block=***,offset=***)),key表示真實資料,tid代表指向資料行的指標,具體block代表頁面號,offset代表行偏移量,指向資料頁面的line pointer,比如執行下面的查詢語句

select * from tbl where id=1000;

key=1000,根據key值在索引中找到tid為5號頁面的1號元組,再通過一號元組行指標找到元組1,檢查元組1的t_ctid欄位,發現指向了新的元組2,於是定位到真實元組資料2。

python中的元組 Python中的元組

一 元組 tuple 元組基本上就像乙個不可改變的列表。與列表一樣支援任意型別的元素 支援巢狀以及常見的序列操作。元組也有一些方法,可用dir tuple 檢視。元組編寫在圓括號中。info 林間 man 1991,7,13,true 支援不同型別 info 林間 man 1991,7,13 tru...

PostgreSQL的除錯攻略

需要軟體 首先當然是 postgresql的源 這個可以去 www.postgresql.org 上面down,現在最新應該是8.1.3,我當前用的是8.1.1版本 另外編譯開發包當然不能少,這個根據各個linux不同版本來獲得 apt get或者rpm包 當然在絕大部分的系統上都已經預設安裝 還有...

PostgreSQL的日誌型別

剛開始學習postgres的時候,可能對postgresql中的日誌概念比較模糊,到底有多少種日誌,哪些日誌是能刪除的,各自又記錄什麼樣的功能。postgresql中有三種日誌,pg log,pg xlog和pg clog。一.安裝路徑 這三種資料庫後兩者一般的安裝路徑是 pgdata 下面的資料夾...