什麼是 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
,還應在整個會話中禁用負載均衡)。你可以通過犧牲效能來避免這個問題。