本章解釋了如何開始使用 Pgpool-II
。
安裝
在本節中,我們假設您已經安裝了 Pgpool-II
與 PostgreSQL
集群。
你的第一個復制(Replication)
在本節中,我們將解釋如何使用 Pgpool-II
管理具有流復制的 PostgreSQL
集群,這是最常見的設置之一。
在繼續之前,您應該正確設置 pgpool.conf
與流復制模式。Pgpool-II
提供了示例配置,配置文件位於 /usr/local/etc
,默認從源代碼安裝。您可以將 pgpool.conf.sample
復制為 pgpool.conf
。
cp /usr/local/etc/pgpool.conf.sample pgpool.conf
如果你打算使用 pgpool_setup
,輸入:
pgpool_setup
這將創建一個具有流復制模式安裝、主 PostgreSQL
安裝和異步備用 PostgreSQL
安裝的 Pgpool-II
。
從現在開始,我們假設您使用 pgpool_setup
在當前目錄下創建安裝。請注意,在執行 pgpool_setup
之前,當前目錄必須是空的。
要啟動整個系統,請輸入:
./startall
系統啟動后,您可以通過向任何數據庫發出名為 show pool_nodes
的偽 SQL
命令來檢查集群狀態。 pgpool_setup
自動創建 test
數據庫。我們使用數據庫。注意端口號是 11000
,這是 pgpool_setup
分配給 Pgpool-II
的默認端口號。
$ psql -p 11000 -c "show pool_nodes" test
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+---------------------
0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 | 2019-01-31 10:23:09
1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 | 2019-01-31 10:23:09
(2 rows)
結果顯示 status
列為 up
,表示 PostgreSQL
已啟動並正在運行,這很好。
測試復制
讓我們使用標准 PostgreSQL
安裝附帶的基准工具 pgbench
來測試復制功能。鍵入以下內容以創建基准表
$ pgbench -i -p 11000 test
要查看 replication
是否正常工作,請直接連接到主服務器和備用服務器,看看它們是否返回相同的結果。
$ psql -p 11002 test
\dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+---------
public | pgbench_accounts | table | t-ishii
public | pgbench_branches | table | t-ishii
public | pgbench_history | table | t-ishii
public | pgbench_tellers | table | t-ishii
(4 rows)
\q
$ psql -p 11003 test
\dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+---------
public | pgbench_accounts | table | t-ishii
public | pgbench_branches | table | t-ishii
public | pgbench_history | table | t-ishii
public | pgbench_tellers | table | t-ishii
(4 rows)
主服務器(端口 11002
)和備用服務器(端口 11003
)返回相同的結果。接下來,讓我們運行 pgbench
一段時間並檢查結果。
$ pgbench -p 11000 -T 10 test
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
duration: 10 s
number of transactions actually processed: 4276
latency average = 2.339 ms
tps = 427.492167 (including connections establishing)
tps = 427.739078 (excluding connections establishing)
$ psql -p 11002 -c "SELECT sum(abalance) FROM pgbench_accounts" test
sum
--------
216117
(1 row)
$ psql -p 11003 -c "SELECT sum(abalance) FROM pgbench_accounts" test
sum
--------
216117
(1 row)
同樣,結果是相同的。
測試負載均衡(Load Balance)
Pgpool-II
允許讀取查詢負載均衡。默認情況下啟用。要查看效果,讓我們使用 pgbench -S
命令。
$ ./shutdownall
$ ./startall
$ pgbench -p 11000 -c 10 -j 10 -S -T 60 test
starting vacuum...end.
transaction type: <builtin: select only>
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 10
duration: 60 s
number of transactions actually processed: 1086766
latency average = 0.552 ms
tps = 18112.487043 (including connections establishing)
tps = 18125.572952 (excluding connections establishing)
$ psql -p 11000 -c "show pool_nodes" test
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+---------------------
0 | /tmp | 11002 | up | 0.500000 | primary | 537644 | false | 0 | 2019-01-31 11:51:58
1 | /tmp | 11003 | up | 0.500000 | standby | 548582 | true | 0 | 2019-01-31 11:51:58
(2 rows)
select_cnt
列顯示有多少 SELECT
被分派到每個節點。由於使用默認配置,Pgpool-II
嘗試調度相同數量的 SELECT
,因此該列顯示幾乎相同的數字。
測試故障轉移(Fail Over)
當 PostgreSQL
服務器宕機時,Pgpool-II
允許自動故障轉移。在這種情況下,Pgpool-II
將服務器的狀態設置為 down
並使用剩余的服務器繼續數據庫操作。
$ pg_ctl -D data1 stop
waiting for server to shut down.... done
server stopped
$ psql -p 11000 -c "show pool_nodes" test
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+---------------------
0 | /tmp | 11002 | up | 0.500000 | primary | 4276 | true | 0 | 2019-01-31 12:00:09
1 | /tmp | 11003 | down | 0.500000 | standby | 1 | false | 0 | 2019-01-31 12:03:07
(2 rows)
備用節點被 pg_ctl
命令關閉。Pgpool-II
檢測到它並分離備用節點。show pool_nodes
命令顯示備用節點處於關閉狀態。您可以在沒有備用節點的情況下繼續使用集群:
$ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test
sum
--------
216117
(1 row)
如果主服務器宕機了怎么辦?在這種情況下,剩余的備用服務器之一被提升為新的主服務器。 對於這個測試,我們從兩個節點都啟動的狀態開始。
$ psql -p 11000 -c "show pool_nodes" test
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+---------------------
0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 | 2019-01-31 12:04:58
1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 | 2019-01-31 12:04:58
(2 rows)
$ pg_ctl -D data0 stop
waiting for server to shut down.... done
server stopped
$ psql -p 11000 -c "show pool_nodes" test
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+---------------------
0 | /tmp | 11002 | down | 0.500000 | standby | 0 | false | 0 | 2019-01-31 12:05:20
1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 | 2019-01-31 12:05:20
(2 rows)
現在主節點從 0
變成了 1
。里面發生了什么?當節點 0
宕機時,Pgpool-II
檢測到它並執行 pgpool.conf
中定義的 failover_command
。這是文件的內容。
#! /bin/sh
# Execute command by failover.
# special values: %d = node id
# %h = host name
# %p = port number
# %D = database cluster path
# %m = new main node id
# %M = old main node id
# %H = new main node host name
# %P = old primary node id
# %R = new main database cluster path
# %r = new main port number
# %% = '%' character
failed_node_id=$1
failed_host_name=$2
failed_port=$3
failed_db_cluster=$4
new_main_id=$5
old_main_id=$6
new_main_host_name=$7
old_primary_node_id=$8
new_main_port_number=$9
new_main_db_cluster=${10}
mydir=/home/t-ishii/tmp/Tutorial
log=$mydir/log/failover.log
pg_ctl=/usr/local/pgsql/bin/pg_ctl
cluster0=$mydir/data0
cluster1=$mydir/data1
date >> $log
echo "failed_node_id $failed_node_id failed_host_name $failed_host_name failed_port $failed_port failed_db_cluster $failed_db_cluster new_main_id $new_main_id old_main_id $old_main_id new_main_host_name $new_main_host_name old_primary_node_id $old_primary_node_id new_main_port_number $new_main_port_number new_main_db_cluster $new_main_db_cluster" >> $log
if [ a"$failed_node_id" = a"$old_primary_node_id" ];then # main failed
! new_primary_db_cluster=${mydir}/data"$new_main_id"
echo $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over
$pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over
sleep 2
fi
該腳本從 Pgpool-II
接收必要的信息作為參數。如果主服務器宕機,它會執行 pg_ctl -D data1 promote
,這應該將備用服務器提升為新的主服務器。
測試在線恢復(Online Recovery)
Pgpool-II
允許通過稱為 Online Recovery
的技術來恢復宕機的節點。 這會將數據從主節點復制到備用節點,以便與主節點同步。 這可能需要很長時間,並且在此過程中可能會更新數據庫。這沒問題,因為在流式配置中,備用服務器將接收 WAL
日志並將其應用於趕上主服務器。為了測試在線恢復,讓我們從之前的集群開始,其中節點 0
處於關閉狀態。
$ pcp_recovery_node -p 11001 -n 0
Password:
pcp_recovery_node -- Command Successful
$ psql -p 11000 -c "show pool_nodes" test
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+---------------------
0 | /tmp | 11002 | up | 0.500000 | standby | 0 | false | 0 | 2019-01-31 12:06:48
1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 | 2019-01-31 12:05:20
(2 rows)
pcp_recovery_node
是 Pgpool-II
安裝附帶的控制命令之一。參數 -p
是指定分配給命令的端口號,它是 pgpool_setup
設置的 11001
。參數 -n
是指定要恢復的節點 id
。執行命令后,節點 0
恢復到 up
狀態。
pcp_recovery_node
執行的腳本在 pgpool.conf
中被指定為 recovery_1st_stage_command
。這是 pgpool_setup
安裝的文件。
#! /bin/sh
psql=/usr/local/pgsql/bin/psql
DATADIR_BASE=/home/t-ishii/tmp/Tutorial
PGSUPERUSER=t-ishii
main_db_cluster=$1
recovery_node_host_name=$2
DEST_CLUSTER=$3
PORT=$4
recovery_node=$5
pg_rewind_failed="true"
log=$DATADIR_BASE/log/recovery.log
echo >> $log
date >> $log
if [ $pg_rewind_failed = "true" ];then
$psql -p $PORT -c "SELECT pg_start_backup('Streaming Replication', true)" postgres
echo "source: $main_db_cluster dest: $DEST_CLUSTER" >> $log
rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \
--exclude postmaster.opts --exclude pg_log \
--exclude recovery.conf --exclude recovery.done \
--exclude pg_xlog \
$main_db_cluster/ $DEST_CLUSTER/
rm -fr $DEST_CLUSTER/pg_xlog
mkdir $DEST_CLUSTER/pg_xlog
chmod 700 $DEST_CLUSTER/pg_xlog
rm $DEST_CLUSTER/recovery.done
fi
cat > $DEST_CLUSTER/recovery.conf $lt;$lt;REOF
standby_mode = 'on'
primary_conninfo = 'port=$PORT user=$PGSUPERUSER'
recovery_target_timeline='latest'
restore_command = 'cp $DATADIR_BASE/archivedir/%f "%p" 2> /dev/null'
REOF
if [ $pg_rewind_failed = "true" ];then
$psql -p $PORT -c "SELECT pg_stop_backup()" postgres
fi
if [ $pg_rewind_failed = "false" ];then
cp /tmp/postgresql.conf $DEST_CLUSTER/
fi
架構基礎
Pgpool-II
是位於客戶端和 PostgreSQL
之間的代理服務器。Pgpool-II
理解 PostgreSQL
使用的稱為 前端和后端協議(frontend and backend protocol)
的線路(wire)級
協議。 有關該協議的更多詳細信息,請參閱 PostgreSQL
手冊。使用 Pgpool-II
不需要修改 PostgreSQL
(更准確地說,您需要一些擴展才能使用 Pgpool-II
的全部功能)。因此 Pgpool-II
可以應對各種 PostgreSQL
版本。理論上,即使是最早的 PostgreSQL
版本也可以與 Pgpool-II
一起使用。對客戶端也可以這樣說。只要它遵循協議,Pgpool-II
就會愉快地接受來自它的連接,無論它使用什么樣的語言或驅動程序。
Pgpool-II
由多個進程組成。有一個主進程,它是所有其他進程的父進程。 它負責分叉子進程,每個子進程都接受來自客戶端的連接。 還有一些從主進程派生的工作進程,負責檢測流復制延遲。還有一個特殊的進程叫做 pcp 進程
,專門用於管理 Pgpool-II
本身。Pgpool-II
有一個內置的高可用性功能,稱為 watchdog
。Watchdog
由一些進程組成。