接上篇postgresql + pgpool 構建容災高可用集群(數據同步流復制/主備自動切換)
本篇主要內容:
- pgpool-ii 安裝
- pgpool-ii 配置
- pgpool-ii 驗證
概述:
在postgresql12 安裝完成之后, 我們需要安裝pool-ii中間件, 來完成 HA 自動切換, ip 自動切換的工作
- 當某一個數據庫掛掉之后, 檢測其生命狀態, 執行相應策略(主庫掛掉, 切換某個備庫為主庫等)
- 當某一個pgpool節點不可用, 其他節點收到信息進行IP轉移(訪問入口接管)
服務器SSH免密設置
為后續使用 hostname 和腳本中 SSH 免登錄:
host 文件添加(2台機器均修改)
10.242.111.204 master
10.242.111.207 slave
10.242.111.203 vip
# 主機/備機操作
su – postgres
-bash-4.2$ ssh-keygen
# 一直enter
-bash-4.2$ ssh-copy-id -i .ssh/id_rsa.pub master
-bash-4.2$ ssh-copy-id -i .ssh/id_rsa.pub slave
pgpool-ii 4.1 安裝(2台機器均安裝)
ftp 文件服務器地址中: https://www.pgpool.net/yum/rpms/4.1/redhat/rhel-7-x86_64/
中間的版本號可以可以更改, 但后續pg版本也需要對應上
yum 在線安裝
#設置rpm源
curl -O https://www.pgpool.net/yum/rpms/4.1/redhat/rhel-7-x86_64/pgpool-II-release-4.1-2.noarch.rpm
rpm -ivh pgpool-II-release-4.1-2.noarch.rpm
#安裝(關於對應的 postgresql 版本,體現在文件名中的 pgXX 這里)
yum -y install pgpool-II-pg12
yum -y install pgpool-II-pg12-debuginfo
yum -y install pgpool-II-pg12-devel
yum -y install pgpool-II-pg12-extensions
rpm離線安裝
# ftp下載rpm離線包
curl -O https://www.pgpool.net/yum/rpms/4.1/redhat/rhel-7-x86_64/pgpool-II-pg12-4.1.2-1pgdg.rhel7.x86_64.rpm
curl -O https://www.pgpool.net/yum/rpms/4.1/redhat/rhel-7-x86_64/pgpool-II-pg12-debuginfo-4.1.2-1pgdg.rhel7.x86_64.rpm
curl -O https://www.pgpool.net/yum/rpms/4.1/redhat/rhel-7-x86_64/pgpool-II-pg12-devel-4.1.2-1pgdg.rhel7.x86_64.rpm
curl -O https://www.pgpool.net/yum/rpms/4.1/redhat/rhel-7-x86_64/pgpool-II-pg12-extensions-4.1.2-1pgdg.rhel7.x86_64.rpm
# 上傳文件到服務器之后, 執行安裝命令
rpm -ivh pgpool*.rpm
補充: 源碼編譯安裝參照官方指定文檔:https://www.pgpool.net/docs/pgpool-II-4.1.2/en/html/installation.html
補充: 舊版中文文檔
目錄/相關命令授權
因為pgpool-ii 配置中會以 postgres 用戶執行一些系統權限命令, 需要使用設置普通用戶授權:
chmod u+x /usr/sbin/ip
chmod u+s /usr/sbin/arping
chmod u+s /sbin/ip
chmod u+s /sbin/ifconfig
配置中相關的日志目錄,pid 目錄權限:
chown postgres.postgres /var/run/pgpool
mkdir -p /var/log/pgpool/
touch /var/log/pgpool/pgpool_status
chown -R postgres.postgres /var/log/pgpool/
pgpool-ii 相關配置(/etc/pgpool-II/)
1. pool_hba.conf (主備相同)
pool_hba.conf 是配置用戶鏈接時的驗證策略, 和postgresql的pg_hba.conf保持一致,要么都是trust,要么都是md5驗證方式,這里采用了md5驗證方式如下設置:
[root@localhost ~] su - postgres
-bash-4.2$ cd /etc/pgpool-II/
-bash-4.2$ vim pool_hba.conf
#編輯內容如下(這里和postgressql設置一樣, trust/md5保持一致)
# IPv4 local connections:
host all all 0.0.0.0/0 md5
host all all 0/0 md5
2. pcp.conf / pool_passwd (主備相同)
這個文件是pgpool管理器自己的用戶名和密碼,用於管理集群的.
-bash-4.2$ pg_md5 postgres
e8a48653851e28c69d0506508fb27fc5
-bash-4.2$ vim pcp.conf
#編輯內容如下:
# USERID:MD5PASSWD
postgres: e8a48653851e28c69d0506508fb27fc5
#在pgpool中添加pg數據庫的用戶名和密碼
[postgres@etc~]$ pg_md5 -p -m -u postgres pool_passwd
#數據庫登錄用戶是postgres,這里輸入登錄密碼,不能出錯
#輸入密碼后,在/etc/pgpoll-II目錄下會生成一個pool_passwd文件
3. pgpool.conf (重點)
這個文件中會配置我們pgpool-ii 節點的關鍵參數, pgpool-ii 自帶提供幾種不同模式的配置文件:
# 執行完前面步驟 /etc/pgpool-II/目錄下的文件, 我們需要用到的
failover.sh (數據庫故障切換腳本)
pcp.conf (用戶訪問驗證策略trust/md5)
pgpool.conf (pgpool-ii 主配置文件)
pool_hba.conf (集群節點密碼管理)
pool_passwd (數據庫密碼管理文件)
recovery_1st_stage.sample (在線故障恢復的腳本示例, 放到postgresql數據目錄/var/lib/pgsql/12/data 下)
主庫pgpool-ii 節點(10.242.111.204-master)
- 常用基礎配置
pid_file_name = '/var/run/pgpool/pgpool.pid'# pid 文件位置, 如果不配置有默認的
logdir = '/var/run/pgpool' # status 文件存儲位置
# 通用
listen_addresses = '*'
port = 9999
pcp_listen_addresses = '*'
pcp_port = 9898
# 后台數據庫鏈接信息配置
backend_hostname0 = 'master' # 第一台數據庫信息
backend_port0 = 5432
backend_weight0 = 1 # 這個權重和后面負載比例相關
backend_data_directory0 = '/var/lib/pgsql/12/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_hostname1 = 'slave' # 第一台數據庫信息
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/var/lib/pgsql/12/data'
backend_flag1 = 'ALLOW_TO_FAILOVER'
# 流復制相關配置
replication_mode = off # pgpool-ii 中復制制模式關閉
load_balance_mode = on # 負載均衡打開
master_slave_mode = on # 主從打開
master_slave_sub_mode = 'stream' # 主從之間模式為流傳輸stream
sr_check_period = 5 # 流復制檢查相關配置
sr_check_user = 'repuser'
sr_check_password = 'repuser'
sr_check_database = 'postgres'
- 數據庫故障轉移(故障后處理)
# 數據庫運行狀況檢查,以便Pgpool-II執行故障轉移: 數據庫的主備切換
health_check_period = 10 # Health check period, Disabled (0) by default
health_check_timeout = 20 # 健康檢查的超時時間,0 永不超時
health_check_user = 'postgres' # 健康檢查的用戶
health_check_password = 'postgres' # 健康檢查的用戶密碼
health_check_database = 'postgres' # 健康檢查的數據庫
# 故障后處理, 為了當postgresql數據庫掛掉之后執行相應的策略
# 這個腳本時放在pgpool的目錄下, 確切的說是由pgpool執行腳本來維護集群中數據庫的狀態
failover_command = '/etc/pgpool-II/failover.sh %H %R '
# follow_master_command = '' # 2台服務器不配置
# 如果使用3台PostgreSQL服務器,則需要指定follow_master_command在主節點故障轉移上的故障轉移后運行。如果有兩個PostgreSQL服務器,則無需follow_master_command設置。
# 具體腳本文件內容見文末
配置文件中傳入的相應參數請參照: config-failover-params
- watchdog(看門狗)配置(用於檢測pgpool-ii 節點狀態, 為后續pgpool故障處理提供依據)
use_watchdog = on # 激活看門狗配置
wd_hostname = 'master' # 當前主機(也可使用IP)
wd_port = 9000 # 工作端口
# 虛擬IP指定
delegate_IP = '10.242.111.203'
if_cmd_path = '/sbin' # 如果if_up_cmd, if_down_cmd 以/開頭, 忽略此配置
# 命令中的`ens160` 請根據自己機器上ip addr 實際的網卡名稱進行修改
# 當前節點啟動指定虛擬IP的命令
if_up_cmd = '/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev ens160 label ens160:0'
# 當前節點指定關閉虛擬IP的命令
if_down_cmd = '/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev ens160'
# watchdog 健康檢查
wd_heartbeat_port = 9694 # 健康檢查端口
wd_heartbeat_keepalive = 2
wd_heartbeat_deadtime = 30
# 其他機器地址配置(多台請增加配置)
heartbeat_destination0 = 'slave'
heartbeat_destination_port0 = 9694
heartbeat_device0 = 'ens160'
# 其他pgpgool節點鏈接信息(多台請增加配置)
other_pgpool_hostname0 = 'slave' # 其他節點地址
other_pgpool_port0 = 9999
other_wd_port0 = 9000 # 其他節點watchdof 端口
# watchdog 發生故障后, 處理的相關配置(宕機, pgpool進程終止)
# 當某個節點故障后,
failover_when_quorum_exists = on
failover_require_consensus = on
allow_multiple_failover_requests_from_node = on
enable_consensus_with_half_votes = on
- 關於watchdog本身(pgpool-ii)發生故障后相關的處理策略, 請務必閱讀官方文檔: CONFIG-WATCHDOG-FAILOVER-BEHAVIOR
- watchdog本身(pgpool-ii節點)本身故障后, 如果配置打開, 其他節點會執行仲裁, 如仲裁從節點中那一個成為主節點, 那一台階段虛擬IP等, 這個仲裁本身有投票機制, 和無視仲裁結果等配置;
- 如果不配置, 主pgpool-i 節點關閉后, 可能不會轉移虛擬IP, 出現集群暫時不可訪問;
- 關於在線恢復(master 恢復后自動變為備庫)
# 此配置將在多個pgpool-ii 節點時無效
recovery_user = 'postgres'
recovery_password = 'postgres'
recovery_1st_stage_command = 'recovery_1st_stage' # 這個腳本時放在postgresql數據目錄下的
- 如果有多個pgpool-ii 節點共同維護集群狀態, 此配置將不可用, 需要手動恢復同步數據>加入集群
備庫pgpool-ii 節點(10.242.111.207-slave)
# 將主庫的配置文件拷貝過來
scp master:/etc/pgpool-II/pool.conf /etc/pgpool-II/pool.conf
# 修改以下幾項即可
wd_hostname = 'slave' # 當前機器
heartbeat_destination0 = 'master' # 其他pg庫機器
other_pgpool_hostname0 = 'master' # 其他pgpool節點機器
啟動驗證
啟動/終止命令
su - postgres
# 啟動命令(日志位置可在命令中指定)
pgpool -n -d -D > /var/log/pgpool/pgpool.log 2>&1 & # 有debug日志
pgpool -n -D > /var/log/pgpool/pgpool.log 2>&1 & # 無debug日志
# 終止命令
pgpool -m fast stop
啟動完成之后, 可登陸虛擬IP, 進行集群狀態查詢
psql -h vip -p9999 -Upostgres -d postgres
#或
psql -h 10.242.111.203 -p9999 -Upostgres -d postgres
查詢結果可見:
[root@slave ~]# psql -h 10.242.111.203 -p9999 -Upostgres -d postgres
Password for user postgres:
psql (12.3)
Type "help" for help.
postgres=# show pool_nodes;
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
0 | master | 5432 | up | 0.500000 | primary | 0 | true | 0 | | | 2020-06-22 17:48:51
1 | slave | 5432 | up | 0.500000 | standby | 0 | false | 0 | | | 2020-06-22 17:48:51
(2 rows)
lb_weight和前面pool.conf配置中backend_weight0 = 1的比例有關;role為postgresql 數據庫的主備狀態;up為數據庫已加入集群管理;- 此時可以通過虛擬IP鏈接, 執行新增/修改/刪除等操作來測試集群正常工作狀態的數據同步;
宕機驗證
1. pgpool-ii 節點宕機(pgpool-ii 進程被終止)
處理關鍵步驟:
- 如果時正常關閉: 釋放虛擬IP > 節點正常關閉 > 其他節點檢測到時區鏈接 > 仲裁選出新的"主節點" > 接管虛擬IP > 正常提供服務
- 如果異常關閉: 其他節點檢測到時區鏈接且IP不可用> 仲裁選出新的"主節點" > 接管虛擬IP > 正常提供服務
```bash
# 在master節點上停止pgpool服務
-bash-4.2$ pgpool -m fast stop
# 原從節點切換完之后,訪問集群
# 可查看/var/log/pgpool/pgpool.log 日志, 可看到被關閉的釋放虛擬IP, 其他節點接管虛擬IP
-bash-4.2$ psql -h vip -p 9999
# 提示輸入密碼:
Type "help" for help.
postgres=# show pool_nodes;
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------
0 | master | 5432 | up | 0.500000 | primary | 0 | false | 0
1 | slave | 5432 | up | 0.500000 | standby | 0 | true | 0
(2 rows)
#訪問成功,在master節點上的pgpool宕機后,由slave節點的pgpool接管vip和集群服務,並未中斷應用訪問。
```
主機日志(/var/log/pgpool/pgpool.log):

備機日志(/var/log/pgpool/pgpool.log):

2. postgresql 數據庫宕機
# 模擬數據庫宕機
systemctl stop postgresql-12
postgres=# show pool_nodes;
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------
0 | master | 5432 | down | 0.500000 | standby | 0 | false | 0
1 | slave | 5432 | up | 0.500000 | primary | 0 | true | 0
(2 rows)
#slave已經被切換成primary,且master節點狀態是down
- master的數據庫掛(primary)掉了,同時變成了standby,pgpool執行數據庫故障切換腳本
failover.sh,slave正在作為新的主數據庫(primary)提供服務 - 這里當master 重啟之后, 需要恢復同步數據, 重新加入集群
# 1. 恢復同步數據
# 2. 清除當前"備庫"上的data目錄
mkdir /var/lib/pgsql/12/data
chmod 0700 data
chown postgres.postgres data
# 3. 執行復制命令
su – postgres
pg_basebackup -h 目標機器IP -p 5432 -U repuser -Fp -Xs -Pv -R -D /var/lib/pgsql/12/data
# 4. 啟動服務(切換到root用戶)
systemctl restart postgresql-12
# 5. 重新將postgresql數據庫加入集群管理(su - postgres)
# -n 節點序號, postgresql 數據庫在集群中的節點序號
pcp_attach_node -d -U postgres -h vip -p 9898 -n 0
# 6. 此時
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------
0 | master | 5432 | up | 0.500000 | standby | 0 | false | 0
1 | slave | 5432 | up | 0.500000 | primary | 0 | true | 0
(2 rows)
- 如果只有一個pgpool-ii 節點, 可以使用pgpool.conf中配置的
recovery_1st_stage_command在線恢復來操作. 多個pgpool節點此配置不支持.
3. 主機直接宕機
- 主機直接宕機, 意味着當前機器時區所有鏈接, 其他pgpool-ii 節點檢測不到原"主pgpool-ii"節點存活
- 首先, 選舉出一個pgpool-ii 節點承擔責任
- 接管維護虛擬IP的責任, 啟動指定的虛擬ip
- 此時檢測到原主數據庫primary不可鏈接, 執行故障轉移腳本, 將當前備庫轉換為主庫為集群提供存儲服務;
總結
- 數據庫postgresql 層面的故障轉移執行切換腳本, 本質上執行的還是
pg_ctl promote命令; - pgpool-ii 層面故障, 后續的檢測/切換虛擬IP, 是不影響下層postgresql數據庫運行狀態的;
- 在主機直接掛掉的情況下, 上面兩個步驟是都要執行的;
- 數據庫宕機恢復的本質依然是同步流復制
pg_basebackup命令; - 即使是pgpool-ii 提供的在線恢復,本質上也是幾個步驟的腳本:
清空備機節點數據目錄 > 使用pg_basebackup命令同步數據 > 啟動數據庫服務 > 將數據庫重新加入集群
