postgresql架構基礎(轉)-(1)


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)。

  1. 接收前端發送過來的查詢(SQL文)
  2. SQL文是單純的文字,電腦是認識不了的,所以要轉換成比較容易處理的內部形式構文樹parser tree,這個處理的稱為構文解析。構文解析的模塊稱為parser.這個階段只能夠使用文字字面上得來的信息,所以只要沒語法錯誤之類的錯誤,即使是select不存在的表也不會報錯。這個階段的構文樹被稱為raw parse tree. 構文處理的入口在raw_parser (parser/parser.c)。
  3. 構文樹解析完以后,會轉換為查詢樹(Query tree)。這個時候,會訪問數據庫,檢查表是否存在,如果存在的話,則把表名轉換為OID。這個處理稱為分析處理(Analyze), 進行分析處理的模塊是analyzer。 另外,PostgreSQL的代碼里面提到構文樹parser tree的時候,更多的時候是指查詢樹Query tree。分析處理的模塊的入口在parse_analyze (parser/analyze.c)
  4. PostgreSQL還通過查詢語句的重寫實現視圖(view)和規則(rule), 所以需要的時候,在這個階段會對查詢語句進行重寫。這個處理稱為重寫(rewrite),重寫的入口在QueryRewrite (rewrite/rewriteHandler.c)。
  5. 通過解析查詢樹,可以實際生成計划樹。生成查詢樹的處理稱為‘執行計划處理’,最關鍵是要生成估計能在最短的時間內完成的計划樹(plan tree)。這個步驟稱為’查詢優化’(不叫query optimize, 而是optimize), 而完成這個處理的模塊稱為查詢優化器(不叫query optimizer,而是optimizer, 或者稱為planner)。執行計划處理的入口在standard_planner (optimizer/plan/planner.c)。
  6. 按照執行計划里面的步驟可以完成查詢要達到的目的。運行執行計划樹里面步驟的處理稱為執行處理‘execute’, 完成這個處理的模塊稱為執行器‘Executor’, 執行器的入口地址為,ExecutorRun (executor/execMain.c)
  7. 執行結果返回給前端。
  8. 返回到步驟一重復執行。

參考文章:

https://wiki.postgresql.org/wiki/Pgsrcstructure

http://www.postgres.cn/docs/9.6/tutorial-arch.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM