1 概述
PostgreSQL官方介紹稱是最先進的開源關系型數據庫,支持所有主流的平台,目前已經更新到了最新版本的12.0,在MySQL被Oracle收購后,PostgreSQL開源社區越來越活躍了,同時還有分布式集群的開源方案GreenPlum,目前也非常受歡迎。本篇文章討論PostgreSQL內部的架構,內部的組件是如何工作的,這對一個DBA是非常重要的內容。
2 PostgreSQL架構
PostgreSQL的物理結構是非常簡單的,主要是由共享內存、后台進程和數據文件組成的。大致的結構可以參考下面的圖。 橢圓形的都是進程,方形的都是內存結構,圓柱形的是文件。
2.1 進程
在啟動數據庫后,Postmaster是第一個啟動的進程,在啟動過程中,會進行恢復操作(如果有事務未正常提交或者回滾的話),初始化共享內存,啟動后台進程等一系列的操作。當客戶進程有一個連接請求時,會創建相對應的后台進程處理。過程如下:
通過ps -ef|grep postgres
查詢可以看到系統總有一個postmaster進程pid=17201,后面所有的后台進程都是postmaster的子進程
postgres 17201 1 0 Jan25 ? 00:06:21 /usr/pgsql-9.6/bin/postgres -D /data1/pgdata
postgres 17202 17201 0 Jan25 ? 00:00:10 postgres: logger process
postgres 17204 17201 0 Jan25 ? 00:01:01 postgres: checkpointer process
postgres 17205 17201 0 Jan25 ? 00:01:39 postgres: writer process
postgres 17206 17201 0 Jan25 ? 00:03:37 postgres: wal writer process
postgres 17207 17201 0 Jan25 ? 00:05:11 postgres: autovacuum launcher process
postgres 17208 17201 0 Jan25 ? 00:00:45 postgres: archiver process
postgres 17209 17201 0 Jan25 ? 00:09:20 postgres: stats collector process
postgres 40377 17201 0 Jan25 ? 00:01:38 postgres: wal sender process replica 10.xxx.xx.115(35258) streaming 1/CD5498D0
下表詳細介紹一下各個進程。
進程 | 詳細描述 |
---|---|
postmaster | 整個數據庫實例的總控進程,負責啟動和關閉該數據庫實例。 |
logger process | 將數據庫的日志寫入到日志文件中 |
checkpointer process | 當檢查點發生時,臟緩存(指的是相對於原數據而言被修改過的)寫入到文件中 |
writer process | 周期性將臟緩存寫入到文件中 |
wal writer process | Write Ahead Log(預寫式日志) |
autovacuum launcher process | 如果autovacuum開啟時,這個是一個周期性回收膨脹表標記為已刪除數據的一個進程 |
archiver process | 當開啟歸檔模式,周期性將WAL日志寫入到指定的目錄 |
stats collector process | 做數據的統計收集工作。主要用於查詢優化時的代價估算,包括一個表和索引進行了多少次的插入、更新、刪除操作,磁盤塊讀寫的次數、行的讀次數。pg_statistic中存儲了該進程收集的各類信息。 |
wal sender process replica | 在開啟流復制的主備模式時,該進程周期性將WAL文件發送到另一台服務器作為數據同步備份。 |
2.2 內存結構
共享內存一般指的是內存中專門為數據庫緩存和事務日志緩存分配的區域,而最重要的組件就是共享緩存和WAL緩存。
共享緩存的主要目的是減少磁盤的IO,比如一些經常訪問的數據塊盡可能長的時間保存在共享緩存中,除此之外還有一些諸如進程、鎖、統計信息也是在緩存中。
WAL緩存區是一塊臨時存儲數據變更的臨時區域,存儲在該緩存區的內容會被周期性寫入到WAL文件中,該區域對於數據庫的備份和恢復都是非常重要的。
2.3 數據庫結構
這里面說的結構是邏輯結構,不討論物理結構。以下是一些理解數據庫結構非常重要的內容。
關於數據庫:
- PostgreSQL是由多個數據庫組成的,也可以稱為數據庫群。
- 當執行了init(),系統會默認創建3個庫:template0,template1,postgres。
- template0和template1是為用戶數據庫創建的模板庫,初始化后,這兩個庫是一模一樣的。
- template1可以被定制修改,用戶創建新的數據庫都是克隆該數據庫的。
關於表空間:
- 在初始化后,默認創建了兩個表空間pg_default和pg_global。
- 如果在創建表時候沒有指定表空間,則默認是pg_default。
- 數據庫群中表的管理默認都是在pg_global中。
- pg_default表空間的物理位置在$PGDATA\base。
- pg_global表空間的物理位置在$PGDATA\global。
關於表:
- 每張表包含三個文件。
- 一個文件用於存儲數據,文件名是表的OID。
- 一個文件用於管理表的空余空間,文件名是OID_fsm。
- 一個文件用於管理表塊的可見性,文件名是OID_vm。
- 索引沒有_vm文件。
3 總結
總體來說,PostgreSQL的架構還是比較容易掌握的。上面總結的也是非常基礎的內容,這個對於日常維護還是使用都是非常重要的。