5、pgpool-II高可用性(一)資料庫的高可用性

lottu發表於2020-12-01

官網示例

一、實現原理

使用 pgpool-II 軟體;我們常用來實現流複製的高可用性;備庫只讀的,不可寫;就是當主庫出現問題時;需要把備庫自動啟用為主庫;來接管服務。

這在其他高可用軟體也有這功能,而 pgpool-II 在配置檔案 pgpool.conf 中提供配置項 failover_command 。讓使用者配置一個指令碼,當發生故障切換時,執行該指令碼。

二、示例演練

本示例採用 PostgreSQL12 + pgpool-II4。

演練目的:

  1. 搭建 pgpool 叢集
  2. 測試資料庫的高可用性
  3. 修復 primary 節點重新加入叢集

2.1、環境規劃

1、PostgreSQL庫的IP/Port規劃

主機名 角色 ip 資料目錄
node3 pgpool 192.168.1.221 9999
node3 primary 192.168.1.221 6000 /data1/postgres/data
node4 standby 192.168.1.202 6000 /data1/postgres/data

2、資料庫使用者規劃

使用者 密碼 用途詳情
postgres 123456 用於線上恢復
replica replica 流複製使用者
pgpool 123456 Pgpool-II health check (health_check_user) replication delay check (sr_check_user)

2.2、資料庫環境準備

1、安裝 PostgreSQL 軟體

N/A

2、安裝 pgpool-II 軟體

檢視 《 pgpool-II安裝 》

本示例涉及到線上恢復;需要安裝 pgpool_recovery

-- 在 primary 操作
psql -c "create extension pgpool_recovery" template1

3、配置 PostgreSQL 資料庫

primary 節點操作

建立資料庫使用者

alter user postgres password '123456';
CREATE ROLE pgpool WITH LOGIN password '123456';;
CREATE ROLE replica WITH REPLICATION LOGIN password 'replica';
--If you want to show "replication_state" and "replication_sync_state" column in SHOW POOL NODES command result, role pgpool needs to be PostgreSQL super user or or in pg_monitor group (Pgpool-II 4.1 or later)
GRANT pg_monitor TO pgpool;

配置歸檔
搭建流複製是不需要配置歸檔;但是線上恢復需要歸檔日誌。

$ mkdir /data1/archivedir
$ vi postgresql.conf
archive_mode = on              
archive_command = 'cp %p /data1/archivedir/%f'
wal_log_hints = on

4、搭建流複製

--在 standby 操作
# 用 root 作業系統使用者在202建立PostgreSQL工作目錄
mkdir -p /data1/postgres/data
chown -R postgres:postgres /data1/postgres/data
chmod 700 /data1/postgres/data
# 用 postgres 作業系統使用者執行 pg_basebackup 命令;進行備庫拷貝
pg_basebackup -F p -R --progress -D /data1/postgres/data -h 192.168.1.221 -p 6000 -U replica
# 用 postgres 作業系統戶用啟動備庫
pg_ctl start

5、配置 ssh 互信

在上面講到的 實現原理,使用Pgpool-II的自動故障轉移和線上恢復;需要 pgpool 服務免密碼在各個機器上執行;以及後續在線上恢復功能;這裡我們使用 postgres 操作使用者。

-- 在pgpool節點執行
$ cd ~/.ssh
$ ssh-keygen -t rsa -f id_rsa_pgpool
$ ssh-copy-id -i id_rsa_pgpool.pub postgres@node3
$ ssh-copy-id -i id_rsa_pgpool.pub postgres@node4
-- 驗證免密碼登入
ssh postgres@serverX -i ~/.ssh/id_rsa_pgpool

6、配置 pgpool

可以查考 《 pgpool 配置 》;這裡我們是用 postgres 操作使用者進行安裝

配置環境變數

export PGHOME=/opt/pg12
export PGDATA=/data1/postgres/data
export PGPOOLHOME=/opt/pgpool
export PATH=$PGHOME/bin:$PATH:$HOME/bin:$PGPOOLHOME/bin

1、設定 pcp 的管理使用者/密碼檔案 pcp.conf
“pcpadm/pgpool123”

#1 進入配置目錄
[postgres@node3 ~]$ cd /opt/pgpool/etc
[postgres@node3 etc]$ cp pcp.conf.sample pcp.conf
# 在該檔案中;使用者/密碼出現在每一行; # USERID:MD5PASSWD
#2 pg_md5 生成配置的使用者名稱密碼是 pgpool123 
[postgres@node3 etc]$ pg_md5 pgpool123
fa039bd52c3b2090d86b0904021a5e33
#3 編輯pcp.conf;這裡配置使用者是 pcpadm,
[postgres@node3 etc]$ vi pcp.conf
# USERID:MD5PASSWD
pcpadm:fa039bd52c3b2090d86b0904021a5e33

2、配置 pool_hba.conf
用於認證使用者登入方式,如客戶端IP限制等,類似於postgresql的pg_hba.conf檔案

[postgres@node3 ~]$ cd /opt/pgpool/etc/
[postgres@node3 etc]$ vi pool_hba.conf
# 新增下面內容
host    all     all     0.0.0.0/0       md5

3、生成 pool_passwd
pgpool 金鑰檔案;通過 pgpool 訪問需要使用者驗證;

這裡暫用資料庫使用者 pgpool

[postgres@node3 ~]$ cd /opt/pgpool/etc/
[postgres@node3 etc]$ pg_md5 --md5auth -u pgpool -p
password: 
[postgres@node3 etc]$ ll pool_passwd 
-rw-r--r--. 1 postgres postgres 132 Nov 30 10:43 pool_passwd

4、配置.pgpass
使用pgpool-II進行故障庫自動切換(failover)、或線上恢復(online recovery)(線上恢復:主庫故障後切換,原主庫恢復後變更為備庫。注意是 Online recovery,而不是自動恢復,需要手工執行命令恢復),需要能夠無密碼 SSH 訪問其他 PostgreSQL 伺服器。為了滿足此條件,我們需要在每個 PostgreSQL 伺服器上,在 postgres 使用者的 home file下建立了.pgpass 檔案,並修改器檔案許可權為600

# su - postgres
$ vi /var/lib/pgsql/.pgpass
server1:5432:replication:repl:<repl user password>
server2:5432:replication:repl:<repl user passowrd>
server3:5432:replication:repl:<repl user passowrd>
$ chmod 600  /var/lib/pgsql/.pgpass

若設定 pg_hba.conf 的該網段免密碼驗證 trust;可以忽略該步驟

host  replication  replica  192.168.1.0/24  trust

5、配置 pcp 的 .pcppass
需要 follow_master_command 指令碼情況下,由於此指令碼必須在不輸入密碼的情況下執行pcp命令,所以我們在 postgres 使用者的home directory下建立.pcppass

# echo 'localhost:9898:pgpool:pgpool' > ~/.pcppass
# chmod 600 ~/.pcppass

6、配置pgpool.conf

listen_addresses = '*'
port = 9999
backend_hostname0 = '192.168.1.221'
backend_port0 = 6000
backend_weight0 = 1
backend_data_directory0 = '/data1/postgres/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_application_name0 = 'server0'
backend_hostname1 = '192.168.1.202'
backend_port1 = 6000
backend_weight1 = 1
backend_data_directory1 = '/data1/postgres/data'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_application_name1 = 'server1'
enable_pool_hba = on
pool_passwd = 'pool_passwd'
pid_file_name = '/opt/pgpool/pgpool.pid'
logdir = '/opt/pgpool'
replication_mode = off
load_balance_mode = on
master_slave_mode = on
master_slave_sub_mode = 'stream'
sr_check_period = 10
sr_check_user = 'pgpool'
sr_check_password = '123456'
sr_check_database = 'postgres'
delay_threshold = 10000000
health_check_period = 5
health_check_user = 'pgpool'
health_check_password = '123456'
health_check_database = 'postgres'
health_check_max_retries = 3
failover_command = '/opt/pgpool/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'
# If we use 3 PostgreSQL servers, we need to specify follow_primary_command to run after failover on the primary node failover. 
# In case of two PostgreSQL servers, follow_primary_command setting is not necessary
# follow_primary_command = '/opt/pgpool/follow_primary.sh %d %h %p %D %m %H %M %P %r %R'
# online recovery
recovery_user = 'postgres'
recovery_password = '123456'
recovery_1st_stage_command = ''
recovery_2nd_stage_command = ''
recovery_timeout = 90

7、配置 failover_command 指令碼

[postgres@node3 ~]$ cd $PGPOOLHOME
[postgres@node3 pgpool]$ cp etc/failover.sh.sample failover.sh
[postgres@node3 pgpool]$ vi failover.sh 
 修改變數 PGHOME
[postgres@node3 pgpool]$ chmod +x failover.sh 

2.3、啟動 pgpool

[postgres@node3 ~]$ pgpool -n > /tmp/pgpool.log  &
[postgres@node3 ~]$ psql -p 9999 postgres  pgpool
2020-12-01 14:50:09: pid 2422: LOG:  new connection received
2020-12-01 14:50:09: pid 2422: DETAIL:  connecting host=[local]
psql (12.2)
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_syn
c_state | last_status_change  
---------+---------------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+----------------
--------+---------------------
 0       | 192.168.1.221 | 6000 | up     | 0.500000  | primary | 0          | false             | 0                 |                   |                
        | 2020-12-01 14:38:09
 1       | 192.168.1.202 | 6000 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                
        | 2020-12-01 14:38:09
(2 rows)

2.4、測試高可用性

1、備份自動啟用為主庫

我們先把主庫停掉,看看備庫是否可以啟用為主庫;

[postgres@node3 ~]$ pg_ctl stop
waiting for server to shut down..... done
server stopped
# 再次檢視節點資訊
[postgres@node3 ~]$ psql -p 9999 postgres  pgpool
2020-12-01 14:53:57: pid 2591: LOG:  new connection received
2020-12-01 14:53:57: pid 2591: DETAIL:  connecting host=[local]
psql (12.2)
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_syn
c_state | last_status_change  
---------+---------------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+----------------
--------+---------------------
 0       | 192.168.1.221 | 6000 | down   | 0.500000  | standby | 0          | false             | 0                 |                   |                
        | 2020-12-01 14:53:07
 1       | 192.168.1.202 | 6000 | up     | 0.500000  | primary | 0          | true              | 0                 |                   |                
        | 2020-12-01 14:53:07
(2 rows)

測試結果: 備庫成功啟用為新主庫
從上面的查詢結果可以看到 “node_id=1”的 role 變成了 “primary”

2、原主庫重加回叢集

現在我們把原主庫加回叢集,變成備庫。後面再演示 online recovery。先手動執行

1、同步時間線

202 備庫提升為新主庫;其時間線 +1;與 221 不同步;這是需要使用pg_rewind同步資料

[postgres@node3 ~]$ pg_rewind --target-pgdata $PGDATA --source-server='host=192.168.1.202 port=6000 user=postgres dbname=postgres password=123456'
pg_rewind: servers diverged at WAL location 0/18000000 on timeline 1
pg_rewind: rewinding from last common checkpoint at 0/17000148 on timeline 1
pg_rewind: Done!

2、配置 postgresql.conf

# 192.168.1.221 
$ cd $PGDATA
$ touch standby.signal
$ vi postgresql.conf
primary_conninfo = 'host=192.168.1.202 port=6000 user=replica'

3、啟動 postgresql

[postgres@node3 ~]$ pg_ctl start

後續講解online recovery。未完待續...

相關文章