天天看點

postgresql架構基礎

PostgreSQL使用一種用戶端/伺服器的模型。一次PostgreSQL會話由下列相關的程序(程式)組成:

一個伺服器程序,它管理資料庫檔案、接受來自用戶端應用與資料庫的聯接并且代表用戶端在資料庫上執行操作。 該資料庫伺服器程式叫做postgres。

那些需要執行資料庫操作的使用者的用戶端(前端)應用。 用戶端應用可能本身就是多種多樣的:可以是一個面向文本的工具, 也可以是一個圖形界面的應用,或者是一個通過通路資料庫來顯示網頁的網頁伺服器,或者是一個特制的資料庫管理工具。 一些用戶端應用是和 PostgreSQL釋出一起提供的,但絕大部分是使用者開發的。
           

和典型的用戶端/伺服器應用(C/S應用)一樣,這些用戶端和伺服器可以在不同的主機上。 這時它們通過 TCP/IP 網絡聯接通訊。 你應該記住的是,在客戶機上可以通路的檔案未必能夠在資料庫伺服器機器上通路(或者隻能用不同的檔案名進行通路)。

PostgreSQL伺服器可以處理來自用戶端的多個并發請求。 是以,它為每個連接配接啟動("forks")一個新的程序。 從這個時候開始,用戶端和新伺服器程序就不再經過最初的 postgres程序的幹涉進行通訊。 是以,主伺服器程序總是在運作并等待着用戶端聯接, 而用戶端和相關聯的伺服器程序則是起起停停。
           

PostgreSQL 結構如下:

Potgres(常駐程序)

管理後端的常駐程序,也稱為’postmaster’。其預設監聽UNIX Domain Socket和TCP/IP(Windows等,一部分的平台隻監聽tcp/ip)的5432端口,等待來自前端的的連接配接處理。監聽的端口号可以在PostgreSQL的設定檔案postgresql.conf裡面可以改。

一旦有前端連接配接過來,postgres會通過fork(2)生成子程序。沒有Fork(2)的windows平台的話,則利用createProcess()生成新的程序。這種情形的話,和fork(2)不同的是,父程序的資料不會被繼承過來,是以需要利用共享記憶體把父程序的資料繼承過來。

Postgres(子程序)

子程序根據pg_hba.conf定義的安全政策來判斷是否允許進行連接配接,根據政策,會拒絕某些特定的IP及網絡,或者也可以隻允許某些特定的使用者或者對某些資料庫進行連接配接。

Postgres會接受前端過來的查詢,然後對資料庫進行檢索,最好把結果傳回,有時也會對資料庫進行更新。更新的資料同時還會記錄在事務日志裡面(PostgreSQL稱為WAL日志),這個主要是當停電的時候,伺服器當機,重新啟動的時候進行恢複處理的時候使用的。另外,把日志歸檔儲存起來,可在需要進行恢複的時候使用。在PostgreSQL 9.0以後,通過把WAL日志傳送其他的postgreSQL,可以實時得進行資料庫複制,這就是所謂的‘資料庫複制’功能。

其他的程序

Postgres之外還有一些輔助的程序。這些程序都是由常駐postgres啟動的程序。

Writer process

Writer process在适當的時間點把共享記憶體上的緩存寫往磁盤。通過這個程序,可以防止在檢查點的時候(checkpoint),大量的往磁盤寫而導緻性能惡化,使得伺服器可以保持比較穩定的性能。Background writer起來以後就一直常駐記憶體,但是并非一直在工作,它會在工作一段時間後進行休眠,休眠的時間間隔通過postgresql.conf裡面的參數bgwriter_delay設定,預設是200微秒。

這個程序的另外一個重要的功能是定期執行檢查點(checkpoint)。

檢查點的時候,會把共享記憶體上的緩存内容往資料庫檔案寫,使得記憶體和檔案的狀态一緻。通過這樣,可以在系統崩潰的時候可以縮短從WAL恢複的時間,另外也可以防止WAL無限的增長。 可以通過postgresql.conf的checkpoint_segments、checkpoint_timeout指定執行檢查點的時間間隔。

WAL writer process

WAL writer process把共享記憶體上的WAL緩存在适當的時間點往磁盤寫,通過這樣,可以減輕後端程序在寫自己的WAL緩存時的壓力,提高性能。另外,非同步送出設為true的時候,可以保證在一定的時間間隔内,把WAL緩存上的内容寫入WAL日志檔案。

Archive process

Archive process把WAL日志轉移到歸檔日志裡。如果儲存了基礎備份以及歸檔日志,即使實在磁盤完全損壞的時候,也可以回複資料庫到最新的狀态。

stats collector process

統計資訊的收集程序。收集好統計表的通路次數,磁盤的通路次數等資訊。收集到的資訊除了能被autovaccum利用,還可以給其他資料庫管理者作為資料庫管理的參考資訊。

Logger process

把postgresql的活動狀态寫到日志資訊檔案(并非事務日志),在指定的時間間隔裡面,對日志檔案進行rotate.

Autovacuum啟動程序

autovacuum launcher process是依賴于postmaster間接啟動vacuum程序。而其自身是不直接啟動自動vacuum程序的。通過這樣可以提高系統的可靠性。

自動vacuum程序

autovacuum worker process程序實際執行vacuum的任務。有時候會同時啟動多個vacuum程序。

wal sender / wal receiver

wal sender 程序和wal receiver程序是實作postgresql複制(streaming replication)的程序。Wal sender程序通過網絡傳送WAL日志,而其他PostgreSQL執行個體的wal receiver程序則接收相應的日志。Wal receiver程序的宿主PostgreSQL(也稱為Standby)接受到WAL日志後,在自身的資料庫上還原,生成一個和發送端的PostgreSQL(也稱為Master)完全一樣的資料庫。

後端的處理流程

下面看看資料庫引擎postgres子程序的處理概要。為了簡單起見下面的說明中,把backend process簡稱為backend。Backend的main函數是PostgresMain (tcop/postgres.c)。

接收前端發送過來的查詢(SQL文)

SQL文是單純的文字,電腦是認識不了的,是以要轉換成比較容易處理的内部形式構文樹parser tree,這個處理的稱為構文解析。構文解析的子產品稱為parser.這個階段隻能夠使用文字字面上得來的資訊,是以隻要沒文法錯誤之類的錯誤,即使是select不存在的表也不會報錯。這個階段的構文樹被稱為raw parse tree. 構文處理的入口在raw_parser (parser/parser.c)。

構文樹解析完以後,會轉換為查詢樹(Query tree)。這個時候,會通路資料庫,檢查表是否存在,如果存在的話,則把表名轉換為OID。這個處理稱為分析處理(Analyze), 進行分析處理的子產品是analyzer。 另外,PostgreSQL的代碼裡面提到構文樹parser tree的時候,更多的時候是指查詢樹Query tree。分析處理的子產品的入口在parse_analyze (parser/analyze.c)

PostgreSQL還通過查詢語句的重寫實作視圖(view)和規則(rule), 是以需要的時候,在這個階段會對查詢語句進行重寫。這個處理稱為重寫(rewrite),重寫的入口在QueryRewrite (rewrite/rewriteHandler.c)。

通過解析查詢樹,可以實際生成計劃樹。生成查詢樹的處理稱為‘執行計劃處理’,最關鍵是要生成估計能在最短的時間内完成的計劃樹(plan tree)。這個步驟稱為’查詢優化’(不叫query optimize, 而是optimize), 而完成這個處理的子產品稱為查詢優化器(不叫query optimizer,而是optimizer, 或者稱為planner)。執行計劃處理的入口在standard_planner (optimizer/plan/planner.c)。

按照執行計劃裡面的步驟可以完成查詢要達到的目的。運作執行計劃樹裡面步驟的處理稱為執行處理‘execute’, 完成這個處理的子產品稱為執行器‘Executor’, 執行器的入口位址為,ExecutorRun (executor/execMain.c)

執行結果傳回給前端。

傳回到步驟一重複執行。