PostgreSQL DBA快速入門(四) - 體系架構

PostgreSQL在開源關係型數據庫市場是最早進的數據庫。他的第一個版本在1989年發佈,從那時開始,他獲得了不少擴展。根據db-enginers上的排名狀況,PostgreSQL目前在數據庫領域排名第四。前端

本篇博客,咱們來討論一下PostgreSQL的內部架構,以及各個組件之間如何交互。這將是本期PostgreSQL DBA系列博客的基石。node

1、PostgreSQL的架構

PostgreSQL的物理架構很是簡單,它由共享內存、一系列後臺進程和數據文件組成。 (以下圖)數據庫

2、Shared Memory

共享內存是服務器服務器爲數據庫緩存和事務日誌緩存預留的內存緩存空間。其中最重要的組成部分是Shared Buffer和WAL Buffer。後端

Shared Buffer

Shared Buffer的目的是減小磁盤IO。爲了達到這個目的,必須知足如下規則:緩存

  • 當須要快速訪問很是大的緩存時(10G、100G等)
  • 若是有不少用戶同時使用緩存,須要將內容儘可能縮小
  • 頻繁訪問的磁盤塊必須長期放在緩存中

WAL Buffer

WAL Buffer是用來臨時存儲數據庫變化的緩存區域。存儲在WAL Buffer中的內容會根據提早定義好的時間點參數要求寫入到磁盤的WAL文件中。在備份和恢復的場景下,WAL Buffer和WAL文件是極其重要的。服務器

3、PostgreSQL 進程類型

PostgreSQL有四種進程類型架構

  1. Postmaster (Daemon) Process(主後臺駐留進程)
  2. Background Process(後臺進程)
  3. Backend Process(後端進程)
  4. Client Process(客戶端進程)

Postmaster Process

主後臺駐留進程是PostgreSQL啓動時第一個啓動的進程。啓動時,他會執行恢復、初始化共享內存愛你的運行後臺進程操做。正常服役期間,當有客戶端發起連接請求時,它還負責建立後端進程。併發

若是經過pstree命令查看進程之間的關係,你會發現Postmaster進程是其餘全部進程的父進程。post

Background Process

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視圖)

Backend Process

最大後臺連接數經過max_connections參數設定,默認值爲100。後端進程用於處理前端用戶請求並返回結果。查詢運行時須要一些內存結構,就是所謂的本地內存(local memory)。本地內存涉及的主要參數有:

  1. work_mem:用於排序、位圖索引、哈希連接和合並連接操做。默認值爲4MB。
  2. maintenance_work_mem:用於vacuum和建立索引操做。默認值爲64MB。
  3. temp_buffers:用於臨時表。默認值爲8MB。

Client Process

客戶端進程須要和後端進程配合使用,處理每個客戶連接。一般狀況下,Postmaster進程會派生一個紫禁城用來處理用戶連接。

4、數據庫結構

想要理解PostgreSQL的數據庫結構,須要先了解一些重要的概念。

數據庫相關概念:

  1. PostgreSQL由一系列數據庫組成。一套PostgreSQL程序稱之爲一個數據庫羣集。
  2. 當initdb()命令執行後,template0 , template1 , 和postgres數據庫被建立。
  3. template0和template1數據庫是建立用戶數據庫時使用的模版數據庫,他們包含系統元數據表。
  4. initdb()剛完成後,template0和template1數據庫中的表是同樣的。可是template1數據庫能夠根據用戶須要建立對象。
  5. 用戶數據庫是經過克隆template1數據庫來建立的;

表空間相關概念:

  1. initdb()後立刻建立pg_default和pg_global表空間。
  2. 建表時若是沒有指定特定的表空間,表默認被存在pg_default表空間中。
  3. 用於管理整個數據庫集羣的表默認被存儲在pg_global表空間中。
  4. pg_default表空間的物理位置爲$PGDATA\base目錄。
  5. pg_global表空間的物理位置爲$PGDATA\global目錄。
  6. 一個表空間能夠被多個數據庫同時使用。此時,每個數據庫都會在表空間路徑下建立爲一個新的子路徑。
  7. 建立一個用戶表空間會在$PGDATA\pg_tblspc目錄下面建立一個軟鏈接,鏈接到表空間制定的目錄位置。

表相關概念:

  1. 每一個表有三個數據文件。
  2. 一個文件用於存儲數據,文件名是表的OID。
  3. 一個文件用於管理表的空閒空間,文件名是OID_fsm。
  4. 一個文件用於管理表的塊是否可見,文件名是OID_vm。
  5. 索引沒有_vm文件,只有OID和OID_fsm兩個文件

其餘須要注意的地方

表和索引建立時文件名是OID,此時的OID和pg_class.relfilenode的值是同樣的。無論怎樣,當咱們執行重寫操做時(truncate,cluster,vacuum full,reindex等),被修改對象的relfilenode值也會被修改,文件名也會隨着reffilenode值一塊兒改變。咱們能夠經過pg_relation_filepath('<object_name>')視圖很容易的檢查文件位置和名稱。

5、運行測試

initdb()完成後,若是登陸數據庫查詢視圖pg_database,咱們能夠看到template0 , template1和 postgres數據庫已經被建立好了。

  • 經過datistemplate列,咱們能夠看到template0和template1是用戶建立數據庫時使用的模版數據庫,其餘的都不是模版數據庫。
  • 經過datlowconn列,能夠看出該數據庫是否容許訪問。由於template0數據庫不能被訪問,因此該數據庫的內容不能被修改。
  • 設置兩個模版數據庫的緣由是template0是初始狀態,而template1數據庫則是能夠集成用戶某些需求的模版數據庫。
  • postgres數據庫時使用模版template1建立的默認數據庫,若是連接時不指定數據庫名稱,默認鏈接到postgres數據庫。
  • 數據庫存儲在$PGDATA\base目錄下。路徑的名稱和數據庫OID的名稱一致。

6、建立用戶數據庫

上文提過,用戶數據庫建立是經過克隆template1數據庫。爲了驗證這個規則,咱們如今template1中建立一個表t1,緊接着建立一個mydb01數據庫,檢查t1表是否在mydb01中存在。

pg_default tablespace

initdb()後,若是登陸數據庫查詢pg_tablespace視圖,會發現pg_global和pg_default表空間已經建立好。

pg_default表空間的位置爲$PGDATA\base。每個數據庫都擁有一個以本身OID命令的子路徑。

pg_global表空間

pg_global表空間用於存儲集羣級別的數據。

  • 例如pg_開頭的表
  • pg_global表空間路徑爲$PGDATA\global.

7、建立用戶表空間

pg_tablespace視圖顯示myts01表空間已經被建立好。

$PGDATA/pg_tblspc路徑下有一個符號連接指到目標目錄。

下面分別鏈接到postgres和mydb01數據庫,建立表。

若是查看/data01路徑下的內容,會發現上面建立的兩個數據庫中的t1表,分別在下面有一個對應OID的文件夾存在。

修改表空間位置

PostgreSQL在建立表空間時指定一個特定的路徑。所以,若是該特定路徑已經滿了,數據就不能在向裏面存儲了。爲了解決該問題,咱們可使用磁盤管理程序擴展空間。可是若是不想使用磁盤管理程序,咱們能夠經過該表表空間的位置來解決該問題。命令以下:

8、Vacuum是什麼?

vacuum執行以下操做:

  1. 收集表和索引的統計信息
  2. 整理表
  3. 清理表和索引中的死亡塊
  4. 被XID凍結,防止XID迴繞

#1 和 #2 是數據庫管理須要的。#3 和 #4 PostgreSQL MVCC 特性的要求。

9、PostgreSQL和Oracle MySQL之間的區別

兩者之間最大的不一樣是MVCC模型和共享池(shared pool)。

指標 ORACLE PostgreSQL
MVCC模型 UNDO Store previous
實現方法 Segment record within block
共享池 exists it does not exist

MVCC模型的區別

爲了增長併發,必須遵循「讀操做不阻塞寫操做,寫操做不阻塞讀操做」的原則。爲了實現這個原則,多版本併發控制(MVCC)理論被引入。Oracle使用UNDO段實現MVCC。而PostgreSQL存儲以前的記錄在數據塊中,它經過事務XID和事務的xmin、xmax來控制事務版本。

Shared Pool

PostgreSQL不提供共享池。這對於熟悉Oracle的用戶來講有點尷尬。共享池是Oracle中最基本和最重要的組件。PostgreSQL在進程級別提供SQL信息的共享能力,而不是共享池。換句話說,若是咱們在同一個進程中屢次執行相同的SQL,它只會硬解析一次。

很是感謝拜讀本篇博客,下次再見~

相關文章
相關標籤/搜索