超詳細(xì)的PG數(shù)據(jù)存儲(chǔ)結(jié)構(gòu):邏輯結(jié)構(gòu)和物理存儲(chǔ)總結(jié)
概述
今天主要講講PG的數(shù)據(jù)結(jié)構(gòu),PG數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)分為:邏輯結(jié)構(gòu)和物理存儲(chǔ)。
其中邏輯存儲(chǔ)結(jié)構(gòu)是內(nèi)部的組織和管理數(shù)據(jù)的方式。物理存儲(chǔ)結(jié)構(gòu)是操作系統(tǒng)中組織和管理數(shù)據(jù)的方式。邏輯存儲(chǔ)結(jié)構(gòu)適用于不同的操作系統(tǒng)和硬件平臺(tái)。
一、邏輯存儲(chǔ)結(jié)構(gòu)
邏輯結(jié)構(gòu)包括:

所有數(shù)據(jù)庫對(duì)象都有各自的oid(object identifiers),oid是一個(gè)無符號(hào)的四字節(jié)整數(shù),相關(guān)對(duì)象的oid都存放在相關(guān)的system catalog表中,比如數(shù)據(jù)庫的oid和表的oid分別存放在pg_database,pg_class表中。
1、數(shù)據(jù)庫集群-Database cluster
2、數(shù)據(jù)庫-Database
3、表空間-tablespace
數(shù)據(jù)庫在邏輯上分成多個(gè)存儲(chǔ)單元,稱作表空間。表空間用作把邏輯上相關(guān)的結(jié)構(gòu)放在一起。數(shù)據(jù)庫邏輯上是由一個(gè)或多個(gè)表空間組成。
新創(chuàng)建的數(shù)據(jù)庫默認(rèn)創(chuàng)建下面的表空間:
1)Catalog表空間 存放系統(tǒng)表信息
2)System表空間 存放用戶數(shù)據(jù)3)Temp表空間
4、模式-Schema
自動(dòng)創(chuàng)建的系統(tǒng)模式如下:
1)PG_CATALOG
2)PG_LARGEOBJECT
3)PG_TOAST
4)PG_PARTITION
默認(rèn)的用戶模式PUBLIC。
5、段-segment
6、區(qū)-extent
7、塊-block
8、數(shù)據(jù)庫對(duì)象-Database object
1)模式對(duì)象表、索引、序列、大對(duì)象、視圖、函數(shù)、存儲(chǔ)過程、觸發(fā)器、包 … …
2)非模式對(duì)象用戶、數(shù)據(jù)庫
9、數(shù)據(jù)表-Table
10、索引-Index
11、序列-Sequence
12、視圖-View
二、物理存儲(chǔ)結(jié)構(gòu)
在執(zhí)行initdb的時(shí)候會(huì)初始化一個(gè)目錄,通常我們都會(huì)在系統(tǒng)配置相關(guān)的環(huán)境變量$PGDATA來表示,初始化完成后,會(huì)再這個(gè)目錄生成相關(guān)的子目錄以及一些文件。在postgresql中,tablespace的概念并不同于其他關(guān)系型數(shù)據(jù)庫,這里一個(gè)tablespace對(duì)應(yīng)的都是一個(gè)目錄。如下圖就是PG的物理結(jié)構(gòu):

1、存儲(chǔ)系統(tǒng)主要包括三個(gè)部分:
內(nèi)存中:buffer,MemoryContext;
數(shù)據(jù)文件,臨時(shí)文件;
日志文件,日志緩存。
2、文件和目錄相關(guān)作用描述:


3、數(shù)據(jù)文件結(jié)構(gòu)

3.1、頁

將數(shù)據(jù)文件中的空間從邏輯上劃分成一個(gè)個(gè)頁面(數(shù)據(jù)塊)。頁面是數(shù)據(jù)庫I/O的基本單位,即只能整頁讀寫數(shù)據(jù)文件, 頁面的大小默認(rèn)是8K。
頁面可以分成兩種:
1)數(shù)據(jù)頁面:數(shù)據(jù)頁面是用來存儲(chǔ)用戶數(shù)據(jù)的。
2)控制頁面:控制頁面用來管理這些數(shù)據(jù)頁面。
數(shù)據(jù)庫共享緩存中的空間劃分也是按頁為基本單位, 一個(gè)頁的大小與數(shù)據(jù)文件中頁的大小一致, 這樣便于整頁讀取數(shù)據(jù)文件,并放入到數(shù)據(jù)庫Buffer中, 從Buffer寫入數(shù)據(jù)文件也同理,保證了緩存與數(shù)據(jù)文件結(jié)構(gòu)和內(nèi)容上的一致性。
3.2、Block(塊)
概念上基本等同于Page, 但Block更多用于說明DMS中對(duì)數(shù)據(jù)文件中Page的描述。
例如: 對(duì)文件的讀寫的操作, 文件讀寫位置的定位, 數(shù)據(jù)文件空間回收等操作, 單位均是以塊進(jìn)行。
數(shù)據(jù)塊的大小在系統(tǒng)初始化時(shí)指定,默認(rèn)是8K,可以取值4K,8K,16K,32K。
3.3、Extent(區(qū))
把數(shù)據(jù)文件中8個(gè)連續(xù)的Page構(gòu)成的空間稱為一個(gè)Extent。Extent是數(shù)據(jù)庫進(jìn)行數(shù)據(jù)文件空間分配/釋放的基本單位。每個(gè)表、索引、序列對(duì)象都是由若干個(gè)區(qū)組成。數(shù)據(jù)文件被創(chuàng)建后,除自動(dòng)保留部分區(qū)作為控制區(qū)外,其他區(qū)全部處于未分配狀態(tài)。表、索引、序列對(duì)象的所有數(shù)據(jù)都存放在Extent中,當(dāng)向這些Extent中插入數(shù)據(jù)時(shí),若該Extent的所有頁面都已占滿,系統(tǒng)就會(huì)自動(dòng)在所屬表空間的數(shù)據(jù)文件中尋找一個(gè)尚未分配的區(qū),并將其狀態(tài)修改為數(shù)據(jù)區(qū)。
3.4、控制頁面
用于空間管理的控制頁面:PFS/GAM/IAM。
用于增量備份的控制頁面:DCM。
判斷可見性的控制頁面:VM。
預(yù)留的控制頁面:BCM/SGAM。
3.5、PFS
Page Free Space,簡(jiǎn)稱PFS頁.
用于記錄本數(shù)據(jù)文件中頁面的空間使用情況。對(duì)文件中的每個(gè)頁面,PFS中都有一個(gè)“字節(jié)”與之對(duì)應(yīng),該字節(jié)記錄了該頁面的狀態(tài)。
PFS頁前64bytes被預(yù)留為頁頭, 剩下81024-64=8128一共覆蓋81288K=64MB空間.
故PFS頁每隔8128個(gè)頁面出現(xiàn)一次, 系統(tǒng)初始化把第一個(gè)PFS頁放在數(shù)據(jù)文件的第二個(gè)頁面位置,即:第1號(hào)數(shù)據(jù)頁面, 由此可知,第N個(gè)PFS頁的位置在8128*N+1.

3.6、GAM
Global Allocation Map,簡(jiǎn)稱GAM頁。
功能:記錄所在數(shù)據(jù)文件的Extent的分配情況,GAM頁中除GAM頭外,剩下空間的每一位(bit)均對(duì)應(yīng)一個(gè)Extent的分配情況。若某bit位為1,則表明該bit位所關(guān)聯(lián)的Extent已被分配出去,反之未被分配。
若一個(gè)GAM頁面大小為8K,則除GAM頭(64 bytes)外,一個(gè)GAM頁面所能覆蓋的文件范圍是: (81024-64)8(88K),約4GB空間。此外,GAM頁每隔881288個(gè)頁面出現(xiàn)一個(gè),系統(tǒng)要求第一個(gè)GAM頁出現(xiàn)在文件的第3個(gè)頁面位置(即:第2個(gè)索引位置),由此得知,第N個(gè)GAM頁的出現(xiàn)位置是: 881288*N+2

3.7、IAM
Index Allocation Map,簡(jiǎn)稱IAM頁。
功能:每個(gè)IAM頁只隸屬于一個(gè)數(shù)據(jù)庫對(duì)象(例如:表),但一個(gè)數(shù)據(jù)庫對(duì)象可包含多個(gè)IAM頁,由此可見IAM頁與數(shù)據(jù)庫對(duì)象的關(guān)系是1對(duì)1,而數(shù)據(jù)庫對(duì)象與IAM頁的關(guān)系是1對(duì)多.
IAM的結(jié)構(gòu)與GAM頁類似,除IAM頭外,剩下空間的每一位(bit)均對(duì)應(yīng)著一個(gè)與IAM相關(guān)的Extent。若某bit位為1,則表明該bit位所關(guān)聯(lián)的Extent已被分配給該IAM,反之未被分配。若一個(gè)IAM頁面大小為8K,則除IAM頭(64 bytes)外,一個(gè)IAM頁面所能覆蓋的文件范圍是: (81024-64)8(88K),約4GB空間。
但與GAM也不同之處在于:IAM的出現(xiàn)位置不固定,只在在創(chuàng)建數(shù)據(jù)庫對(duì)象的時(shí)候才分配。

三、邏輯與物理存儲(chǔ)關(guān)系
1、邏輯關(guān)系存在表空間;
2、表空間存在對(duì)應(yīng)的數(shù)據(jù)文件中;
新創(chuàng)建的數(shù)據(jù)庫對(duì)應(yīng)的數(shù)據(jù)文件的名稱:
Catalog表空間 – databasename.dbf
System表空間 – Udatabasename.dbf
Temp表空間-- Tdatabasename.dbf
- 前面加 “U” 前綴代表用戶數(shù)據(jù)表空間,用于保存用戶表的數(shù)據(jù)。
- 不帶 U 代表 是系統(tǒng)表的表空間,用于保存系統(tǒng)表的數(shù)據(jù)。
- U 前綴的數(shù)據(jù)文件代表的表空間名為PG。
- 不帶U 的數(shù)據(jù)文件代表的表空間為 CATALOG。
四、數(shù)據(jù)庫文件、表空間、其他文件之間的關(guān)系
1、關(guān)系圖如下:

說明:
1)每一個(gè)數(shù)據(jù)庫具有一個(gè)或多個(gè)數(shù)據(jù)文件,用戶存放數(shù)據(jù)庫的所有數(shù)據(jù)。
2)數(shù)據(jù)庫的數(shù)據(jù)文件有以下特征:
- 一個(gè)數(shù)據(jù)庫文件只能與一個(gè)數(shù)據(jù)庫的一個(gè)表空間相連。
- 一個(gè)表空間可以由多個(gè)數(shù)據(jù)文件組成。
3)數(shù)據(jù)庫對(duì)象與文件關(guān)系:
- 數(shù)據(jù)庫對(duì)象放到表空間中。
- 表空間有多個(gè)數(shù)據(jù)文件。
- 表空間中有多個(gè)數(shù)據(jù)庫對(duì)象。
4)數(shù)據(jù)庫對(duì)象邏輯上是存儲(chǔ)在表空間中,物理上是存儲(chǔ)在與表空間相關(guān)聯(lián)的數(shù)據(jù)文件中。
2、數(shù)據(jù)庫包含的文件種類:
1)數(shù)據(jù)庫文件:data/DB
數(shù)據(jù)庫對(duì)象,如:數(shù)據(jù)庫、表,索引,序列等對(duì)象。
2)控制文件:data/CTL
用來記錄數(shù)據(jù)庫集群的狀態(tài)信息,如:版本信息、集群所管理的各種文件信息、檢查點(diǎn)信息、事務(wù)狀態(tài)信息等。
3)日志文件:data/REDOLOG
記錄數(shù)據(jù)修改操作的日志,用于系統(tǒng)發(fā)生故障時(shí)進(jìn)行數(shù)據(jù)恢復(fù)。
4)臨時(shí)文件:data/DB
存放數(shù)據(jù)庫進(jìn)行計(jì)算的過程中,生成的各種中間對(duì)象,如排序運(yùn)算的外存歸并單元。
5)參數(shù)文件:data目錄下
五、Postgresql 底層存儲(chǔ)管理方式:
Postgresql的每個(gè)數(shù)據(jù)庫均存放在一個(gè)目錄中,以db_oid命名,該目錄中存放每個(gè)表對(duì)應(yīng)的文件,文件名以該數(shù)據(jù)表對(duì)應(yīng)的relfilenode_oid命名。當(dāng)表中的數(shù)據(jù)量足夠大,導(dǎo)致表文件的大小大于1GB的時(shí)候,postgresql會(huì)自動(dòng)創(chuàng)建新的文件用于存放新插入的數(shù)據(jù)。新文件的名稱為: relfilenode_iod.1, relfilenode_iod.2 等。使用該策略是為了防止在某些文件系統(tǒng)中,最大支持文件尺寸不能大于1GB的情形。
db_oid, relfilenode_oid可以從pg_class系統(tǒng)表中查詢得出。
每個(gè)table對(duì)應(yīng)的文件內(nèi)部又按照Page的方式組織。每個(gè)Page的大小默認(rèn)為8KB。所以每個(gè)數(shù)據(jù)庫對(duì)應(yīng)文件的Disk 分布由下圖所示:

每個(gè)Page中包含Page Header以及Data段,Page Header中,pg_lower指向Free Space的起始地址,pg_upper指向Free Space的結(jié)束地址。
- Data 段中,包含有: ItemIdData 段,F(xiàn)ree Space段, Items段 以及Special space段。
- ItemIdData 段: Array of (offset,length) pairs pointing to the actual items. 4 bytes per item.
- Free Space 段:The unallocated space. New item pointers are allocated from the start of this area, new items from the end.
- Items 段: The actual items themselves.
- Special space 段: Index access method specific data. Different methods store different data. Empty in ordinary tables.
- Item的存儲(chǔ)是從pg_upper向pg_lower(類似堆)方向增長(zhǎng)。ItenIdData的存儲(chǔ)是從pg_lower向pg_upper方向增長(zhǎng)(類似棧)。