什么是 Pgpool-II?
Pgpool II
管理一個 PostgreSQL
服務器池,以實現單個 PostgreSQL
安裝無法實現的一些功能。這些功能包括:
高可用
Pgpool-II
通過使用多個PostgreSQL
服務器提供高可用性 (HA
) 功能,以便它自動從服務器池中刪除損壞的服務器以繼續執行數據庫任務。這稱為自動故障轉移(automatic failover)
。Pgpool-II
還為Pgpool-II
本身提供了一個HA
功能,稱為Watchdog
。此外,Pgpool-II
采用復雜的仲裁算法來避免誤報錯誤和腦裂問題,使整個HA
系統高度可靠。
負載均衡
Pgpool-II
將讀取查詢分布在多個PostgreSQL
服務器上以獲得更高的性能。此功能稱為負載平衡。 寫查詢被發送到主服務器(在流復制模式下)或所有服務器(在原生復制模式和快照隔離模式下)。在任何情況下,Pgpool-II
都會自動區分讀查詢和寫查詢。
除了這些基本功能之外,Pgpool-II
還提供了一些有用的功能,例如:
連接池
Pgpool-II
維護與PostgreSQL
服務器的已建立連接,並在具有相同屬性(即用戶名、數據庫、協議版本和其他連接參數,如果有的話)的新連接進入時重用它們。它減少了連接開銷,並改進了 系統的整體吞吐量。
在線恢復
Pgpool-II
可以通過執行一條命令進行數據庫節點的在線恢復。 當在線恢復與自動故障轉移一起使用時,通過故障轉移分離的節點可以自動附加為備用節點。 也可以同步和附加新的PostgreSQL
服務器。
限制超出的連接
PostgreSQL
的最大並發連接數是有限制的,當達到這個數量時,新的連接會被拒絕。 但是,提高此最大連接數會增加資源消耗並對整體系統性能產生負面影響。Pgpool-II
對最大連接數也有限制,但是額外的連接會排隊而不是立即返回錯誤。 但是,您可以配置為在超出連接限制時返回錯誤(4.1 或更高版本)。
Watchdog
Watchdog
可以協調多個Pgpool-II
,創建一個健壯的集群系統,避免單點故障或腦裂。 為避免腦裂,您至少需要3
個Pgpool-II
節點。Watchdog
可以針對其他pgpool-II
節點執行生命檢查,以檢測Pgpool-II
的故障。如果活動Pgpool-II
宕機,備用Pgpool-II
可以升級為活動,並接管Virtual IP
。
內存中查詢緩存
- 在內存中查詢緩存允許保存一對
SELECT
語句及其結果。如果有相同的SELECT
進入,Pgpool-II
從緩存中返回值。由於不涉及SQL
解析和對PostgreSQL
的訪問,因此使用內存緩存非常快。 另一方面,在某些情況下它可能比正常路徑慢,因為它增加了存儲緩存數據的一些開銷。
Pgpool-II
使用 PostgreSQL
的后端和前端協議,並在后端和前端之間中繼消息。 因此,數據庫應用程序(前端)認為 Pgpool-II
是實際的 PostgreSQL
服務器,而服務器(后端)將 Pgpool-II
視為其客戶端之一。因為 Pgpool-II
對服務器和客戶端都是透明的,所以現有的數據庫應用程序可以與 Pgpool-II
一起使用,幾乎不需要更改其源代碼。
Pgpool-II
適用於 Linux
、FreeBSD
和大多數類 UNIX
架構。不支持 Windows
。支持的 PostgreSQL
服務器版本為 7.4
或更高版本(某些功能可能不適用於舊版本的 PostgreSQL
)。您還必須確保所有 PostgreSQL
服務器都使用相同的主要版本。除此之外,我們不建議將不同的 PostgreSQL
安裝與不同的構建選項混合使用:包括是否支持 SSL
、是否使用 --disable-integer-datetimes
、不同的塊大小。這些可能會影響 Pgpool-II
的部分功能。PostgreSQL
次要版本的差異通常不是問題。但是,我們不會測試所有出現的次要版本,我們建議使用完全相同的 PostgreSQL
次要版本。
Pgpool-II 簡史
Pgpool-II
的生命始於 Tatsuo Ishii
的個人項目。在項目中它只是一個簡單的連接池軟件。所以 Pgpool
這個名字來源於這個事實。第一個版本於 2003
年公開。
2004
年,Pgpool 1.0
發布,帶有原生復制功能(基於 SQL
語句的復制)。同年 2.0
發布了負載均衡,並支持第 3
版前端/后端協議。2005
年,添加了自動故障轉移和主從模式支持。
2006
年,Pgpool
更名為 Pgpool-II
。第一個版本 1.0
取消了 Pgpool
中的許多限制,例如 Pgpool
中 PostgreSQL
服務器的數量最多為 2
個。 還添加了許多新功能,例如並行查詢模式和 PCP
命令(PCP
代表 "Pgpool Control Protocol"
)。Pgpool
和 Pgpool-II
之間最重要的變化可能是項目從個人項目更改為 Pgpool Development Group
擁有的團體項目。
約定
在命令概要中使用以下約定:括號([
和 ]
)表示可選部分。(在 Tcl
命令的概要中,使用問號 (?
) 代替,這在 Tcl
中很常見。)大括號({
和 }
)和豎線(|
)表示您必須選擇一種替代方法。點 (...
) 表示前面的元素可以重復。
在提高清晰度的地方,SQL
命令前面有提示符 =>
,shell
命令前面有提示符 $
。 但是,通常不會顯示提示。
administrator
通常是負責安裝和運行服務器的人。用戶可以是正在使用或想要使用 Pgpool-II
系統的任何部分的任何人。這些術語不應被解釋得太狹隘;本文檔沒有關於系統管理程序的固定假設。
更多的信息
網站
Pgpool-II
網站是提供有關Pgpool-II
官方信息的中心位置:下載、文檔、常見問題解答、郵件列表存檔等。
郵件列表
- 郵件列表是回答您的問題、與其他用戶分享經驗以及聯系開發人員的好地方。有關詳細信息,請參閱
Pgpool-II
網站。
你自己!
pgpool-II
是一個開源項目。因此,它依賴於用戶社區的持續支持。當您開始使用Pgpool-II
時,您將依賴其他人的幫助,無論是通過文檔還是通過郵件列表。考慮回饋您的知識。閱讀郵件列表並回答問題。 如果您學到了文檔中沒有的內容,請將其寫下來並貢獻出來。如果您向代碼添加功能,請貢獻它們。
限制
本節介紹 Pgpool-II
的當前限制。
PostgreSQL
的功能
- 如果您使用
pg_terminate_backend()
停止后端,這將觸發故障轉移。發生這種情況的原因是PostgreSQL
為終止的后端發送與完全關閉postmaster
完全相同的消息。3.6
版之前沒有解決方法。從版本3.6
開始,此限制已得到緩解。如果函數的參數(即進程 ID
)是常量,則可以安全地使用該函數。 在擴展協議模式下,您無法使用該功能。
負載均衡
多語句查詢(單行多個 SQL
命令)總是發送到主節點(在流復制模式下)或主節點(在其他模式下)。通常 Pgpool-II
將查詢分派到適當的節點,但不適用於多語句查詢。
身份驗證/訪問控制
-
在
replication
模式或native replication
模式下,支持trust
和pam
方法。自Pgpool-II 3.0
起也支持md5
。 使用身份驗證文件pool_passwd
支持md5
。自Pgpool-II 4.0
起,還支持scram-sha-256
、證書和明文密碼。pool_passwd
是認證文件的默認名稱。以下是啟用md5
身份驗證的步驟:- 以數據庫的操作系統用戶身份登錄並輸入:
pg_md5 --md5auth --username=your_username your_passwd
用戶名和
md5
加密密碼注冊到pool_passwd
中。 如果pool_passwd
還不存在,pg_md5
命令會自動為你創建它。pool_passwd
的格式是username:encrypted_passwd
。- 您還需要將適當的
md5
條目添加到pool_hba.conf
。 - 請注意,用戶名和密碼必須與在
PostgreSQL
中注冊的相同。 - 更改
md5
密碼后(當然在pool_passwd
和PostgreSQL
中),您需要執行pgpool reload
。
大對象
- 在流復制模式下,
Pgpool-II
支持大對象。 - 在原生復制模式下,如果后端是
PostgreSQL 8.1
或更高版本,Pgpool-II
支持大對象。為此,您需要在pgpool.conf
中啟用lobj_lock_table
指令。但是,不支持使用后端函數lo_import
進行大對象復制。 - 在其他模式下,包括 Slony 模式,不支持大對象。
臨時表
- 創建/插入/更新/刪除臨時表始終在原生復制模式下的主節點上執行。 這些表上的
SELECT
也在primary
表上執行。但是,如果臨時表名在SELECT
中用作文字,則無法檢測到它,並且SELECT
將進行負載均衡。 這將觸發"not found the table"
錯誤或將找到另一個具有相同名稱的表。 為避免此問題,請使用SQL
注釋。 - 請注意,用於訪問系統目錄的查詢中使用的此類文字表名稱確實會導致上述問題。
psql
的\d
命令產生這樣的查詢:
SELECT 't1'::regclass::oid;
在這種情況下,Pgpool-II
總是將查詢發送到主節點並且不會導致問題。
如果您使用的是 PostgreSQL 8.3
或更高版本,則通過在 reset_query_list
中指定 DISCARD ALL
將在會話結束時刪除由 CREATE TEMP TABLE
創建的表。
對於 8.2.x
或更早版本,由 CREATE TEMP TABLE
創建的表在退出會話后不會被刪除。這是因為連接池,從 PostgreSQL
的后端角度來看,它使會話保持活動狀態。為避免這種情況,您必須通過發出 DROP TABLE
顯式刪除臨時表,或在事務塊內使用 CREATE TEMP TABLE ... ON COMMIT DROP
。
Native Replication 模式下的函數等
無法保證使用上下文相關機制(例如 random number
, transaction ID
, OID
, SERIAL
, sequence
)提供的任何數據將在多個后端正確復制。 對於 SERIAL
,啟用 insert_lock
將有助於復制數據。insert_lock
還有助於 SELECT setval()
和 SELECT nextval()
。
使用 CURRENT_TIMESTAMP
、CURRENT_DATE
、now()
的 INSERT/UPDATE
將被正確復制。使用 CURRENT_TIMESTAMP
、CURRENT_DATE
、now()
作為默認值的表的 INSERT/UPDATE
也將被正確復制。 這是通過在查詢執行時用從 primary
獲取的常量替換這些函數來完成的。 但是有一些限制:
在 Pgpool-II 3.0
或之前的版本中,在某些情況下,表默認值中時態數據的計算並不准確。 例如下面的表定義:
CREATE TABLE rel1(
d1 date DEFAULT CURRENT_DATE + 1
)
被視為:
CREATE TABLE rel1(
d1 date DEFAULT CURRENT_DATE
)
Pgpool-II 3.1
或更高版本可以正確處理這些情況。 因此,"d1"
列將明天作為默認值。但是,如果使用擴展協議(例如,在 JDBC
、PHP PDO
中使用)或 PREPARE
,則此增強不適用。
請注意,如果列類型不是時間類型,則不執行重寫。這樣的例子:
foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision)
假設我們有下表:
CREATE TABLE rel1(
c1 int,
c2 timestamp default now()
)
我們可以復制
INSERT INTO rel1(c1) VALUES(1)
因為這變成
INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09')
然而,
INSERT INTO rel1(c1) SELECT 1
無法轉換,因此無法在當前實現中正確復制。 仍然會插入值,根本沒有任何轉換。
SQL 類型命令
SQL
類型的命令不能用於擴展查詢模式。
多字節字符
Pgpool-II
不會在客戶端和PostgreSQL
之間對多字節字符進行編碼轉換。客戶端和后端的編碼必須相同。
多語句查詢
Pgpool-II
不能處理多語句查詢。但是,當Pgpool-II
通過psql
連接時,是沒有問題的。psql
解析多條語句,逐個發送一條語句。
libpq
libpq
在構建Pgpool-II
時被鏈接。libpq
版本必須是3.0
或更高版本。使用libpq 2.0
版構建Pgpool-II
將失敗。
參數狀態
- 當客戶端連接到
PostgreSQL
時,PostgreSQL
將一些parameter/value
對發送回客戶端。該協議稱為ParameterStatus
。參數/值對可以通過libpq
的PQParameterStatus
等API
提取。Pgpool-II
從多個PostgreSQL
服務器收集ParameterStatus
值,並且這些值可能在服務器之間有所不同。一個典型的例子是in_hot_standby
,它是在PostgreSQL 14
中引入的。該變量的值在主服務器為off
和備用服務器上為on
。問題是,Pgpool-II
必須只返回其中一個客戶端。 在這種情況下,它選擇主服務器報告的值。所以PQParameterStatus
將返回off
。 另一方面,當客戶端發出show in_hot_standby
時,返回值可以on
或off
,具體取決於會話的負載均衡節點。 - 請注意,如果服務器之間的值不同,
Pgpool-II
將發出除in_hot_standby
之外的日志消息。這是為了防止日志文件被淹沒,因為in_hot_standby
總是不同的。
set_config
PostgreSQL
具有set_config
功能,它允許在當前會話中更改參數值,如SET
命令(實際上set_config
比SET
具有更多功能。有關詳細信息,請參閱PostgreSQL
手冊)。當Pgpool-II
在集群模式設置為streaming_replication
的情況下運行時,它只將函數發送到主服務器。由於該函數不發送到備用服務器,因此每個服務器的參數值不同。為避免該問題,您可以使用SET
命令代替set_config
。 由於SET
命令已發送到用於此會話的所有服務器,因此不會發生此問題。但是,如果您使用超過2
個PostgreSQL
服務器,則需要禁用statement_level_load_balance
並使用SET
命令。這是因為,如果啟用了statement_level_load_balance
,查詢可能會發送到除主服務器和分配給負載均衡節點的服務器之外的第三台服務器。- 如果需要使用
set_config
,請關閉session
的負載均衡(不僅對於set_config
,還應在整個會話中禁用負載均衡)。你可以通過犧牲性能來避免這個問題。