PostgreSQL在開源關係型數據庫市場是最早進的數據庫。他的第一個版本在1989年發佈,從那時開始,他獲得了不少擴展。根據db-enginers上的排名狀況,PostgreSQL目前在數據庫領域排名第四。前端
本篇博客,咱們來討論一下PostgreSQL的內部架構,以及各個組件之間如何交互。這將是本期PostgreSQL DBA系列博客的基石。node
PostgreSQL的物理架構很是簡單,它由共享內存、一系列後臺進程和數據文件組成。 (以下圖)數據庫
共享內存是服務器服務器爲數據庫緩存和事務日誌緩存預留的內存緩存空間。其中最重要的組成部分是Shared Buffer和WAL Buffer。後端
Shared Buffer的目的是減小磁盤IO。爲了達到這個目的,必須知足如下規則:緩存
WAL Buffer是用來臨時存儲數據庫變化的緩存區域。存儲在WAL Buffer中的內容會根據提早定義好的時間點參數要求寫入到磁盤的WAL文件中。在備份和恢復的場景下,WAL Buffer和WAL文件是極其重要的。服務器
PostgreSQL有四種進程類型架構
主後臺駐留進程是PostgreSQL啓動時第一個啓動的進程。啓動時,他會執行恢復、初始化共享內存愛你的運行後臺進程操做。正常服役期間,當有客戶端發起連接請求時,它還負責建立後端進程。併發
若是經過pstree命令查看進程之間的關係,你會發現Postmaster進程是其餘全部進程的父進程。post
PostgreSQL操做須要的後臺進程列表以下:測試
進程 | 做用 |
---|---|
logger | 將錯誤信息寫到log日誌中 |
checkpointer | 當檢查點出現時,將髒內存塊寫到數據文件 |
writer | 週期性的將髒內存塊寫入文件 |
wal writer | 將WAL緩存寫入WAL文件 |
Autovacuum launcher | 當自動vacuum被啓用時,用來派生autovacuum工做進程。autovacuum進程的做用是在須要時自動對膨脹表執行vacuum操做。 |
archiver | 在歸檔模式下時,複製WAL文件到特定的路徑下。 |
stats collector | 用來收集數據庫統計信息,例如會話執行信息統計(使用pg_stat_activity視圖)和表使用信息統計(pg_stat_all_tables視圖) |
最大後臺連接數經過max_connections參數設定,默認值爲100。後端進程用於處理前端用戶請求並返回結果。查詢運行時須要一些內存結構,就是所謂的本地內存(local memory)。本地內存涉及的主要參數有:
客戶端進程須要和後端進程配合使用,處理每個客戶連接。一般狀況下,Postmaster進程會派生一個紫禁城用來處理用戶連接。
想要理解PostgreSQL的數據庫結構,須要先了解一些重要的概念。
數據庫相關概念:
表空間相關概念:
表相關概念:
表和索引建立時文件名是OID,此時的OID和pg_class.relfilenode的值是同樣的。無論怎樣,當咱們執行重寫操做時(truncate,cluster,vacuum full,reindex等),被修改對象的relfilenode值也會被修改,文件名也會隨着reffilenode值一塊兒改變。咱們能夠經過pg_relation_filepath('<object_name>')視圖很容易的檢查文件位置和名稱。
initdb()完成後,若是登陸數據庫查詢視圖pg_database,咱們能夠看到template0 , template1和 postgres數據庫已經被建立好了。
上文提過,用戶數據庫建立是經過克隆template1數據庫。爲了驗證這個規則,咱們如今template1中建立一個表t1,緊接着建立一個mydb01數據庫,檢查t1表是否在mydb01中存在。
initdb()後,若是登陸數據庫查詢pg_tablespace視圖,會發現pg_global和pg_default表空間已經建立好。
pg_default表空間的位置爲$PGDATA\base。每個數據庫都擁有一個以本身OID命令的子路徑。
pg_global表空間用於存儲集羣級別的數據。
pg_tablespace視圖顯示myts01表空間已經被建立好。
$PGDATA/pg_tblspc路徑下有一個符號連接指到目標目錄。
下面分別鏈接到postgres和mydb01數據庫,建立表。
若是查看/data01路徑下的內容,會發現上面建立的兩個數據庫中的t1表,分別在下面有一個對應OID的文件夾存在。
PostgreSQL在建立表空間時指定一個特定的路徑。所以,若是該特定路徑已經滿了,數據就不能在向裏面存儲了。爲了解決該問題,咱們可使用磁盤管理程序擴展空間。可是若是不想使用磁盤管理程序,咱們能夠經過該表表空間的位置來解決該問題。命令以下:
vacuum執行以下操做:
#1 和 #2 是數據庫管理須要的。#3 和 #4 PostgreSQL MVCC 特性的要求。
兩者之間最大的不一樣是MVCC模型和共享池(shared pool)。
指標 | ORACLE | PostgreSQL |
---|---|---|
MVCC模型 | UNDO | Store previous |
實現方法 | Segment | record within block |
共享池 | exists | it does not exist |
爲了增長併發,必須遵循「讀操做不阻塞寫操做,寫操做不阻塞讀操做」的原則。爲了實現這個原則,多版本併發控制(MVCC)理論被引入。Oracle使用UNDO段實現MVCC。而PostgreSQL存儲以前的記錄在數據塊中,它經過事務XID和事務的xmin、xmax來控制事務版本。
PostgreSQL不提供共享池。這對於熟悉Oracle的用戶來講有點尷尬。共享池是Oracle中最基本和最重要的組件。PostgreSQL在進程級別提供SQL信息的共享能力,而不是共享池。換句話說,若是咱們在同一個進程中屢次執行相同的SQL,它只會硬解析一次。
很是感謝拜讀本篇博客,下次再見~