文檔結構:php
因爲博主以前是Oracle dba,oracle 高可用通常是rac,以及搭建ADG,一個是基於實例的高可用,一個是基於數據的容災,甚至也有rac+adg的方式。Postgres有同步和異步兩種同步方式,我發現,mysql,oracle,postgresql 這兩種同步模式原理都是一個德行,可能都是繞不開關係型數據庫吧。html
異步方式主庫上的事務不會等待備庫接受日誌流發出確認信息後主庫才向客戶端返回成功,同步方式事務會主庫等待至少一個備庫接受日誌流發出確認信息後便返回成功;很明顯,異步時間會有延遲,同步會增長相應時間,可是保證了數據的一致性,在資源容許的狀況下,能夠一主多從且採起一個備庫同步,多個備庫異步方式。前端
除了pgpool異步高可用,還能夠採用keepalived方式,本次就簡單實驗pgpool異步方式。node
什麼是pgpool-Ⅱmysql
Pgpool-II是一個在PostgreSQL服務器和PostgreSQL數據庫客戶端之間工做的中間件。它是根據BSD許可證受權的。它提供如下功能。sql
鏈接池數據庫
Pgpool-II保存與PostgreSQL服務器的鏈接,並在具備相同屬性(即用戶名,數據庫,協議版本)的新鏈接進入時重用它們。它減小了鏈接開銷,並提升了系統的總體吞吐量。後端
複製緩存
Pgpool-II能夠管理多個PostgreSQL服務器。使用複製功能能夠在2個或更多物理磁盤上建立實時備份,以便在磁盤發生故障時服務能夠繼續運行而不會中止服務器。bash
負載均衡
若是複製了數據庫,則在任何服務器上執行SELECT查詢都將返回相同的結果。Pgpool-II利用複製功能,經過在多個服務器之間分配SELECT查詢來減小每一個PostgreSQL服務器的負載,從而提升系統的總體吞吐量。充其量,性能與PostgreSQL服務器的數量成比例地提升。在許多用戶同時執行許多查詢的狀況下,負載平衡最有效。
限制超出鏈接
PostgreSQL的最大併發鏈接數有限制,鏈接在這麼多鏈接後被拒絕。可是,設置最大鏈接數會增長資源消耗並影響系統性能。pgpool-II對最大鏈接數也有限制,但額外鏈接將排隊,而不是當即返回錯誤。
看家狗
Watchdog能夠協調多個Pgpool-II,建立一個強大的集羣系統,避免單點故障或腦裂。看門狗能夠對其餘pgpool-II節點執行生命檢查,以檢測Pgpoll-II的故障。若是活動Pgpool-II發生故障,則能夠將備用Pgpool-II提高爲活動狀態,並接管虛擬IP。
在內存查詢緩存中
在內存中查詢緩存容許保存一對SELECT語句及其結果。若是有相同的SELECT,Pgpool-II將從緩存中返回值。因爲不涉及SQL解析或訪問PostgreSQL,所以在內存緩存中使用速度很是快。另外一方面,在某些狀況下,它可能比正常路徑慢,由於它增長了存儲緩存數據的一些開銷。
Pgpool-II講PostgreSQL的後端和前端協議,並在後端和前端之間傳遞消息。所以,數據庫應用程序(前端)認爲Pgpool-II是實際的PostgreSQL服務器,服務器(後端)將Pgpool-II視爲其客戶端之一。由於Pgpool-II對服務器和客戶端都是透明的,因此現有的數據庫應用程序能夠與Pgpool-II一塊兒使用。Pgpool-II講述PostgreSQL的後端和前端協議,並在它們之間傳遞鏈接。所以,數據庫應用程序(前端)認爲Pgpool-II是實際的PostgreSQL服務器,服務器(後端)將Pgpool-II視爲其客戶端之一。由於Pgpool-II對服務器和客戶端都是透明的,因此現有的數據庫應用程序能夠與Pgpool-II一塊兒使用,幾乎不須要更改其源碼。
如下測試主要來自譚峯(francs)老師的《postgres 實戰》
主機名 |
說明 |
IP地址 |
端口 |
版本 |
10pg1 |
主庫 |
192.168.10.41 |
5432 |
Postgres10.8 |
pgpool主 |
5555 |
|
||
VIP |
192.168.10.61 |
|||
10pg2 |
備庫 |
192.168.10.51 |
5433 |
Postgres10.8 |
pgpool備 |
5555 |
|
其中,應用鏈接vip,防火牆建議關閉,同時,生產上確定不是postgres這庫了,確定時業務庫了,這個按照實際狀況配置。
https://www.pgpool.net/mediawiki/index.php/Downloads
我是採用rpm的最新版本4.0.6。
yum -y install libmemcached
export PATH=$PATH:/usr/local/pgsql/bin/
mkdir /pgpool
./configure --prefix=/pgpool --with-pgsql=/pgpool/
make
make install
安裝生成的配置文件在/pgpool/ 目錄下。
注意若是提示:
configure: error: libpq is not installed or libpq is old
若是配置了環境變量(PATH,PGHOME,PGDATA)仍是出現以上錯誤,建議使用
./configure --prefix=/pgpool
make
make install
並把pgpool配置到環境變量中(root,postgres用戶下)
我用postgres 執行故障轉移腳本,因此進行互信設置把
vi /etc/hosts
192.168.10.41 10pg1
192.168.10.52 10pg2
ssh-keygen
ssh-copy-id postgres@10pg2
同理在備庫上執行
ssh-keygen
ssh-copy-id postgres@10pg1
測試:
ssh postgres@10pg2
ssh postgres@10pg1
Postgres針對鏈接策略須要配置pg_hba.conf文件,而pgpool鏈接中因爲應用程序是線鏈接pgpool,而後經過pgpool再鏈接到後端數據庫,所以也須要在pgpool層面進行鏈接配置。
Pgpool的配置跟pg_hba.conf同樣的。
cd /pgpool/etc/
cp pool_hba.conf.sample pool_hba.conf
vi pool_hba.conf
加上192.168.10.0 這個網段的ip 均可以的訪問
host all all 0.0.0.0/0 md5
默認文件是不存在的,生成pool_passwd配置文件
pg_md5 命令生成
pg_md5 -u postgres -m 密碼
或者 手工建一個文件,怕密碼泄露
select rolpassword from pg_authid where rolname='postgres';
vi pool_passwd
postgres:md53175bce1d3201d16594cebf9d7eb3f9d
rep:md5df2c887bcb2c49b903aa33bdbc5c2984
cp /pgpool/etc/pgpool.conf.sample-stream /pgpool/etc/pgpool.conf
vi /pgpool/etc/pgpool.conf
須要修改的(因爲參數太多直接寫結果吧):
主庫參數配置:
port = 5555
listen_addresses = '*' #表示監聽全部地址鏈接(跟postgres參數同樣的意思)
backend_hostname0 = '192.168.10.41' #配置節點0的hostname
backend_port0 = 5432 #主庫端口
backend_weight0 = 1 #沒有開啓模式參數配不配之均可以
backend_data_directory0 = '/pgsql/pg_data' #節點0數據目錄
backend_flag0 = 'ALLOW_TO_FAILOVER' #主庫是否容許故障轉移
backend_hostname1 = '192.168.10.51'
backend_port1 = 5433
backend_weight1 = 1
backend_data_directory1 = '/pgsql/pg_data'
backend_flag1 = 'ALLOW_TO_FAILOVER'
enable_pool_hba = on #表示啓用pool_hba.conf
pool_passwd = 'pool_passwd' #設置MD5認證的密碼文件
log_destination = 'syslog' #日誌
pid_file_name = '/pgpool/pgpool.pid'
load_balance_mode = off #關閉負載均衡(若是開啓,select語句會在備庫執行)
master_slave_mode = on
master_slave_sub_mode = 'stream'
sr_check_period = 10 #流複製檢查10s
sr_check_user = 'rep' #我同步採用的rep 用戶
sr_check_password = 'rep'
sr_check_database = 'postgres' #流複製檢查鏈接的數據庫
delay_threshold = 10000000 這個是備庫延遲wal/xlog日誌大於10000000字節,將不會select語句分發到備庫
health_check_period= 5
health_check_timeout = 20
health_check_user = 'rep'
health_check_password = 'rep'
health_check_database = 'postgres'
health_check_max_retries = 3
health_check_retry_delay = 3
failover_command = '/pgpool/etc/failover_stream.sh %d %P %H %R'
use_watchdog = on #啓用watchdog
wd_hostname = '192.168.10.41'
wd_port = 9000
wd_priority = 1 ##表示watchdog的優先級,級別越高則被選爲主節點,一主一從設置同樣
delegate_IP = '192.168.10.61' #設置的VIP
if_cmd_path = '/sbin'
if_up_cmd = 'ip addr add $_IP_$/24 dev eth0 label eth0:0' 個人環境是eth0
if_down_cmd = 'ip addr del $_IP_$/24 dev eth0'
heartbeat_destination0 = '192.168.10.51'
heartbeat_destination_port0 = 9694
heartbeat_device0 = 'eth0'
wd_life_point = 3 #當探測pgpool節點失敗後設置重試次數
wd_lifecheck_query = 'SELECT 1'
wd_lifecheck_dbname = 'postgres'
wd_lifecheck_user = 'rep'
wd_lifecheck_password = 'rep'
other_pgpool_hostname0 = '10pg2' #設置遠程pgpool節點主機
other_pgpool_port0 = 5555 #設置遠程pgpool端口號
other_wd_port0 = 9000 #設置遠程pgpool節點watchdog端口號
從庫參數配置:
port = 5555
listen_addresses = '*' #表示監聽全部地址鏈接(跟postgres參數同樣的意思)
backend_hostname0 = '192.168.10.41' #配置節點0的hostname
backend_port0 = 5432 #端口
backend_weight0 = 1 #沒有開啓模式參數配不配之均可以
backend_data_directory0 = '/pgsql/data' #節點0數據目錄
backend_flag0 = 'ALLOW_TO_FAILOVER' #節點0是否容許故障轉移
backend_hostname1 = '192.168.10.51' #節點1的主機名
backend_port1 = 5433 #節點1的端口
backend_weight1 = 1 #沒有開啓模式參數配不配之均可以
backend_data_directory1 = '/pgsql/data' #節點1數據目錄
backend_flag1= 'ALLOW_TO_FAILOVER' #節點1是否容許故障轉移
enable_pool_hba = on #表示啓用pool_hba.conf
pool_passwd = 'pool_passwd' #設置MD5認證的密碼文件
log_destination = 'syslog' #日誌
pid_file_name = '/pgpool/pgpool.pid'
load_balance_mode = off #關閉負載均衡(若是開啓,select語句會在備庫執行)
master_slave_mode = on
master_slave_sub_mode = 'stream'
sr_check_period = 10 #流複製檢查10s
sr_check_user = 'rep' #我同步採用的rep 用戶
sr_check_password = 'rep'
sr_check_database = 'postgres' #流複製檢查鏈接的數據庫
delay_threshold = 10000000 這個是備庫延遲wal/xlog日誌大於10000000字節,將不會select語句分發到備庫
health_check_period= 5
health_check_timeout = 20
health_check_user = 'rep'
health_check_password = 'rep'
health_check_database = 'postgres'
health_check_max_retries = 3
health_check_retry_delay = 3
failover_command = '/pgpool/etc/failover_stream.sh'
use_watchdog = on #啓用watchdog
wd_hostname = '10pg2'
wd_port = 9000
wd_priority = 1 ##表示watchdog的優先級,級別越高則被選爲主節點,一主一從設置同樣
delegate_IP = '192.168.10.61' #設置的VIP
if_cmd_path = '/sbin'
if_up_cmd = 'ip addr add $_IP_$/24 dev eth0 label eth0:0' 個人環境是eth0
if_down_cmd = 'ip addr del $_IP_$/24 dev eth0'
heartbeat_destination0 = '192.168.10.41'
heartbeat_destination_port0 = 9694
heartbeat_device0 = 'eth0'
wd_life_point = 3 #當探測pgpool節點失敗後設置重試次數
wd_lifecheck_query = 'SELECT 1'
wd_lifecheck_dbname = 'postgres'
wd_lifecheck_user = 'rep'
wd_lifecheck_password = 'rep'
other_pgpool_hostname0 = '192.168.10.41' #設置遠程pgpool節點主機
other_pgpool_port0 = 5555 #設置遠程pgpool端口號
other_wd_port0 = 9000 #設置遠程pgpool節點watchdog端口號
cat /pgpool/etc/failover_stream.sh
#! /bin/bash
# Executes this command after master failover
# Special values:
# %d = node id
# %h = host name
#! /bin/bash
# Executes this command after master failover
# Special values:
# %d = node id
# %h = host name
# %p = port number
# %D = database cluster path
# %m = new master node id
# %H = hostname of the new master node
# %M = old master node id
# %P = old primary node id
# %r = new master port number
# %R = new master database cluster path
# %% = '%' character
falling_node=$1
old_primary=$2
new_primary=$3
pgdata=$4
pghome=/usr/local/pgsql/
log=/pgpool/failover.log
date >> $log
#輸出變量到日誌,方便此腳本出現異常時調試
echo "falling_node=$falling_node" >> $log
echo "old_primary=$old_primary" >> $log
echo "new_primary=$new_primary" >> $log
echo "pgdata=$pgdata" >> $log
##若是故障的數據庫爲主庫而且執行腳本的操做系統用戶爲root
if [ $falling_node = $old_primary ] && [ $UID -eq 0 ];then
if [ -f $pgdata/recovery.conf ];then
su postgres -c "$pghome/bin/pg_ctl promote -D $pgdata"
echo "Local promote" >> $log
else
su postgres -c "ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata"
echo "Remote promote" >> $log
fi
fi
exit 0;
腳本主要是經過有沒有recovery.conf文件來判斷爲主備,會調用ip addr添加或者刪除IP地址,使用root維護pgpool程序會方便些。須要給root 添加環境變量:
export PGPOOL_HOME=/pgpool
export PATH=$PATH:$HOME/bin:/pgpool/bin/:$PGPOOL_HOME/bin
在主庫上啓動pgpool(root用戶)
pgpool
查看主庫啓動的vip
查看日誌:
查看p'g'pool參數的使用:
我的感受跟pg_ctl 相似,尤爲是加載參數:
pgpool reload
或者關閉pgpool -m fast stop
Shutdown modes are:
smart quit after all clients have disconnected
fast quit directly, with proper shutdown
immediate the same mode as fast
關閉是這三種狀態
日誌查看是:
tail -100f /var/log/messages
後面啓動從庫pgpool:
主庫日誌:
從庫日誌:
若是從庫起不來 或者報錯,那確定是參數設置錯了,根據日誌去修改參數,值得注意的是,這裏面參數不少是本庫的,也有不少是遠端庫的,必定要配置對。
經過vip 查看pgpool 狀態:
psql -h 192.168.10.61 -p5555 postgres
show pool_nodes;
悲劇的是主庫竟然pgpool 狀態爲down,也就是日誌說的node 0 0,正常應該node 0 2;
反覆檢查參數配置沒有錯,因而執行(通常主備庫重啓後,狀態異常能夠執行如下語句):
pcp_attach_node -h 192.168.10.61 -U pgpool 0
注意,0爲節點1,若是是備庫有問題,就是pcp_attach_node -h 192.168.10.61 -U pgpool 1,而後就正常了
以下圖:
若是主備庫關閉過,也須要從新鏈接pgpool
pcp_attach_node -h 192.168.10.61 -U pgpool 0或者1
pgpool提供一個用於管理pgpool 的系統層命令工具,pcp用戶屬於pgpool 層面,和數據庫中的用戶沒有關係,例如查看pgpool 節點信息,增長pgpool 節點,斷開pgpool 節點等。
例如,我設置PCP層面密碼爲pgpool
[root@10pg1 ~]# pg_md5 pgpool
ba777e4c2f15c11ea8ac3be7e0440aa0
cd /pgpool/etc/
cp pcp.conf.sample pcp.conf
添加到
vi pcp.conf
pcp命令查看pcp節點,watchdog信息等。
pcp_node_info --verbose -h 192.168.10.61 -U pgpool 0
Status 字段值意思:
0爲初始化
1爲以啓動沒有鏈接
2爲以啓動有連接
3節點關閉
查看watchdog集羣信息:
pcp_watchdog_info --verbose -h 192.168.10.61 -U pgpool
停掉主節點的pgpool 程序
pgpool -m stop fast
查看主庫IP:
主庫已經刪除了VIP 61
查看系統日誌:
主庫:
備庫:
備庫接管了VIP
登陸進去查看:
psql -h 192.168.10.61 -p5555 postgres postgres
雖然備庫接管了VIP,可是沒有發生failover切換,單獨的pgpool程序故障並不會發生數據庫主備切換(主機數據庫宕機除外,待會測試)。
把主庫上的pgpool開啓,主庫服務器沒有接管VIP,重啓一下備庫pgpool,讓主庫接管vip,再啓動備庫pgpool作關閉數據庫測試。
pg_ctl stop -D /pgsql/pg_data -m fast
查看備庫日誌:
查看VIP
能夠查看的是VIP 雖然仍然再10pg1上,可是其實如今鏈接的時新主庫:
測試:
已經發生failover.
查看新主庫:
Failover 成功。查看關閉的庫failover的日誌:
這個日誌時再原主庫上生成的failover日誌
從新搭建主從同步。
關閉主庫主機至關於關閉數據庫和pgpool了,我的猜測時vip 會飄過來,也會執行備庫提高爲主庫。
select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;
show pool_nodes;
關閉主庫服務器。
通過幾秒鐘VIP漂移過來了,並且備庫提高爲主庫了。
查看新主庫pgpool日誌:
查看新主庫發生failover的日誌:
查看新主庫信息
按照步驟來安裝以及測試,若是參數沒有配置錯誤,實驗仍是會比較成功。值得注意的時要配置pool_passwd和pcp密碼,以及pgpool參數文件配置的時候,不要把主從參數配錯了,最後更值得注意的時failover腳本,若是寫錯了不會發生故障轉移,再重啓過數據庫或者pgpool程序時,若是pgpool節點狀態不正常,能夠利用pcp_attach_node把pgpool節點加進去,感受備庫切換主庫的時候,不是立馬,有點延遲,應該是跟時間參數配置有關。
原文出處:https://www.cnblogs.com/hmwh/p/11632281.html