PostgreSQL 企業級高可用 repmgr 架構部署

Whoami:5年+金融、政府、醫療領域工作經驗的DBA
Certificate:OCP、PCP
Skill:Oracle、Mysql、PostgreSQL
Platform:CSDN、墨天倫、公衆號(呆呆的私房菜)

閱讀本文可以瞭解使用 repmgr 擴展實現 PostgreSQL 數據庫高可用的相關內容,包含 repmgr 高可用架構基本原理、搭建部署及主備切換等。

01 repmgr 概述

02 repmgr 基本原理

03 repmgr 高可用架構搭建

jC14Hh

1. 主機環境配置
cat >> /etc/sysctl.conf <<-EOF
kernel.shmmax = 4294967296
kernel.shmall = 2097152
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.aio-max-nr = 1048576
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144    
net.core.rmem_max = 4194304    
net.core.wmem_default = 262144    
net.core.wmem_max = 4194304
fs.file-max = 6815744
EOF
2. 配置主機資源限制
cat >> /etc/security/limits.conf <<-EOF
* soft    nofile  1024000
* hard    nofile  1024000
* soft    nproc   unlimited
* hard    nproc   unlimited
* soft    core    unlimited
* hard    core    unlimited
* soft    memlock unlimited
* hard    memlock unlimited
EOF
3. 安裝系統依賴
yum -y install coreutils glib2 lrzsz mpstat dstat sysstat e4fsprogs xfsprogs ntp readline-devel zlib-devel openssl-devel pam-devel libxml2-devel libxslt-devel python-devel tcl-devel gcc make smartmontools flex bison perl-devel perl-ExtUtils* openldap-devel jadetex openjade bzip2 gettext json-c json-c-devel curl-devel
4. 源碼安裝PostgreSQL數據庫和repmgr擴展(所有主機執行)
-- 創建安裝用戶
useradd postgres
echo "postgres#2024" | passwd --stdin postgres
-- 配置用戶環境變量
cat >> /home/postgres/.bash_profile <<-EOF
export PGHOME=/pg/pg11
export PGDATA=/pg/pg11/data
export PATH=\$PATH:\$PGHOME/bin
EOF
chown postgres.postgres ~/.bash_profile
-- 上傳postgresql-11.18.tar.gz安裝包到/pg/pg11下
cd /pg/pg11/
tar xzf postgresql-11.18.tar.gz
cd postgresql-11.18
./configure --prefix=/pg/pg11 --enable-nls --with-perl --with-python --with-tcl --with-gssapi --with-openssl --with-pam --with-ldap --with-libxml --with-libxslt
make -j 4 && make install
-- 上傳repmgr-5.3.1.tar.gz安裝包到 /pg/pg11/postgresql-11.18/contrib下
cd /pg/pg11/postgresql-11.18/contrib
tar xzf repmgr-5.3.1.tar.gz
cd repmgr-5.3.1
./configure && make && make install
5. 主機互信創建(所有主機執行)
cat >> /etc/hosts <<-EOF
192.168.56.11 pgdb01
192.168.56.12 pgdb02
192.168.56.13 pgdb03
192.168.56.14 pgdb04
EOF
ssh-keygen -t rsa
-- 主節點執行
ssh pgdb01 "cat ~/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
ssh pgdb02 "cat ~/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
ssh pgdb03 "cat ~/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
ssh pgdb04 "cat ~/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
scp ~/.ssh/authorized_keys pgdb-02:~/.ssh/
scp ~/.ssh/authorized_keys pgdb-03:~/.ssh/
scp ~/.ssh/authorized_keys pgdb-04:~/.ssh/
-- 所有主機執行
chmod 644 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
6. 初始化主庫
initdb -E UTF8 --locale=en_US.utf8 -U postgres
7. 主庫配置
-- 修改數據庫參數配置
cat >> $PGDATA/postgresql.conf <<EOF
listen_addresses = '*'
port=5432
unix_socket_directories='/pg/pg11/data'
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%a.log'
log_truncate_on_rotation = on
wal_level='replica'
archive_mode='on'
archive_command='test ! -f /pg/pg11/archive/%f && cp %p /pg/pg11/archive/%f'
hot_standby=on
max_wal_senders=10
wal_sender_timeout=60s
wal_keep_segments = 128 
max_replication_slots=10
wal_log_hints=on
shared_preload_libraries ='repmgr'
EOF
-- 修改訪問白名單配置
cat >> $PGDATA/pg_hba.conf <<EOF
host    replication     all             0.0.0.0/0               md5
local   repmgr          repmgr                                  md5
host    repmgr          repmgr          127.0.0.1/32            md5
host    repmgr          repmgr          192.168.56.0/24         md5
local   replication     repmgr                                  md5
host    replication     repmgr          127.0.0.1/32            md5
host    replication     repmgr          192.168.56.0/24         md5
EOF
-- 主庫創建用戶
createuser -s repmgr -h127.0.0.1 -Upostgres
createdb repmgr -O repmgr -h127.0.0.1 -Upostgres
psql -Upostgres -h 127.0.0.1 -c "alter user repmgr with password 'repmgr#2024';"
psql -Upostgres -h 127.0.0.1 -c "select name, setting from pg_settings where name in ('wal_level','archive_mode','archive_command');"
8. repmgr配置
-- 主庫執行
cat > $PGHOME/repmgr.conf <<EOF
node_id=1
node_name=pgdb01
conninfo='host=192.168.56.11 user=repmgr password=repmgr#2024 dbname=repmgr connect_timeout=2'
data_directory='/pg/pg11/data' 
pg_bindir='/pg/pg11/bin'
EOF
-- 從庫1執行
cat > $PGHOME/repmgr.conf <<EOF
node_id=2
node_name=pgdb02
conninfo='host=192.168.56.12 user=repmgr password=repmgr#2024 dbname=repmgr connect_timeout=2'
data_directory='/pg/pg11/data' 
pg_bindir='/pg/pg11/bin'
EOF
-- 從庫2執行
cat > $PGHOME/repmgr.conf <<EOF
node_id=3
node_name=pgdb03
conninfo='host=192.168.56.13 user=repmgr password=repmgr#2024 dbname=repmgr connect_timeout=2'
data_directory='/pg/pg11/data' 
pg_bindir='/pg/pg11/bin'
EOF
-- 所有節點都配~/.pgpass密碼文件
cat >> ~/.pgpass <<EOF
192.168.56.11:5432:repmgr:repmgr:repmgr#2024
192.168.56.12:5432:repmgr:repmgr:repmgr#2024
192.168.56.13:5432:repmgr:repmgr:repmgr#2024
192.168.56.14:5432:repmgr:repmgr:repmgr#2024
192.168.56.11:5432:replication:repmgr:repmgr#2024
192.168.56.12:5432:replication:repmgr:repmgr#2024
192.168.56.13:5432:replication:repmgr:repmgr#2024
192.168.56.14:5432:replication:repmgr:repmgr#2024
EOF
chmod 0600 ~/.pgpass
-- 註冊主庫服務
repmgr -f $PGHOME/repmgr.conf primary register
psql -Urepmgr -h127.0.0.1 -c "select * from repmgr.nodes;"
-- 註冊從庫1服務
repmgr -h 192.168.56.11 -U repmgr -d repmgr -f $PGHOME/repmgr.conf standby clone --dry-run
repmgr -h 192.168.56.11 -U repmgr -d repmgr -f $PGHOME/repmgr.conf standby clone
pg_ctl start 
repmgr -h 192.168.56.11 -U repmgr -d repmgr -f $PGHOME/repmgr.conf standby register
psql -Urepmgr -h127.0.0.1 -c "select * from repmgr.nodes;"
repmgr -f $PGHOME/repmgr.conf cluster show
-- 註冊從庫2服務
repmgr -h 192.168.56.11 -U repmgr -d repmgr -f $PGHOME/repmgr.conf standby clone --dry-run
repmgr -h 192.168.56.11 -U repmgr -d repmgr -f $PGHOME/repmgr.conf standby clone
pg_ctl start 
repmgr -h 192.168.56.11 -U repmgr -d repmgr -f $PGHOME/repmgr.conf standby register
psql -Urepmgr -h127.0.0.1 -c "select * from repmgr.nodes;"
repmgr -f $PGHOME/repmgr.conf cluster show
-- 見證節點配置
-- 注意:見證節點不需要克隆,初始化數據庫即可
initdb -E UTF8 --locale=en_US.utf8 -U postgres
-- 修改數據庫配置
cat >> $PGDATA/postgresql.conf <<EOF
listen_addresses = '*'
port=5432
unix_socket_directories='/pg/pg11/pgdata'
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%a.log'
log_truncate_on_rotation = on
wal_level='replica'
archive_mode='on'
archive_command='test ! -f /pg/pg11/archive/%f && cp %p /pg/pg11/archive/%f'
hot_standby=on
max_wal_senders=10
wal_sender_timeout=60s
wal_keep_segments = 128 
max_replication_slots=10
wal_log_hints=on
shared_preload_libraries ='repmgr'
-- 修改訪問白名單配置
host    replication     all             0.0.0.0/0               md5
local   repmgr          repmgr                                  md5
host    repmgr          repmgr          127.0.0.1/32            md5
host    repmgr          repmgr          192.168.56.0/24        md5
local   replication     repmgr                                  md5
host    replication     repmgr          127.0.0.1/32            md5
host    replication     repmgr          192.168.56.0/24        md5
-- 見證節點創建用戶
createuser -s repmgr -h127.0.0.1 -Upostgres
createdb repmgr -O repmgr -h127.0.0.1 -Upostgres
psql -Upostgres -h 127.0.0.1 -c "alter user repmgr with password 'repmgr#2024';"
psql -Upostgres -h 127.0.0.1 -c "select * from pg_settings where name in ('wal_level','archive_mode','archive_command');"
-- 見證節點repmgr配置文件
cat > $PGHOME/repmgr.conf <<EOF
node_id=4
node_name=pgdb-04
conninfo='host=192.168.56.14 user=repmgr password=repmgr#2024 dbname=repmgr connect_timeout=2'
data_directory='/pg/pg11/data'
pg_bindir='/pg/pg11/bin'
EOF
-- 註冊見證節點服務
repmgr -h 192.168.56.11 -U repmgr -d repmgr -f $PGHOME/repmgr.conf witness register
repmgr -f $PGHOME/repmgr.conf cluster show
9. 檢查repmgr服務
repmgr -f $PGHOME/repmgr.conf cluster matrix 
repmgr -f $PGHOME/repmgr.conf cluster crosscheck  
repmgr -f $PGHOME/repmgr.conf node status
repmgr -f $PGHOME/repmgr.conf node check
10. 自動故障轉移配置
cat >> /pg/pg11/repmgr.conf <<-EOF
monitoring_history=yes
monitor_interval_secs=5
failover=automatic
reconnect_attempts=6
reconnect_interval=5
promote_command='repmgr standby promote -f /pg/pg11/repmgr.conf --log-to-file'
follow_command='repmgr standby follow -f /pg/pg11/repmgr.conf --log-to-file --upstream-node-id=%n'
log_level=INFO
log_status_interval=10
log_file='/pg/pg11/repmgr.log'
EOF
11. 日誌輪詢配置
cat >> /etc/logrotate.conf <<"EOF"
/pg/pg11/repmgr.log {
missingok
compress
rotate 30
daily
dateext
create 0600 postgres postgres
}
EOF
12. 所有節點啓動repmgrd進程
echo "repmgrd -f /pg/pg11/repmgr.conf --pid-file /tmp/repmgrd.pid --daemonize" >> /etc/rc.local
chmod +x /etc/rc.d/rc.local
repmgrd -f /pg/pg11/repmgr.conf --pid-file /tmp/repmgrd.pid --daemonize

04 repmgr 切換

repmgr 切換分爲兩種,一種是手動主備切換,一種是故障自動切換。

切換目標:主節點切換成從節點,從節點1切換成主節點
1. 檢查所有節點狀態
repmgr -f /pg/pg11/repmgr.conf cluster show
2. 預執行,從節點1執行切換,必須保證ssh通訊正常
repmgr -f /pg/pg11/repmgr.conf standby switchover --siblings-follow --dry-run --log-level DEBUG --force-rewind
3. 從節點1執行切換
repmgr -f /pg/pg11/repmgr.conf standby switchover --siblings-follow --force-rewind --log-level DEBUG --verbose
目標: 模擬主庫宕機,從節點自動切換成主節點
1. 停止主庫
pg_ctl stop
2. 查看從節點是否切換爲主節點
repmgr -f /pg/pg11/repmgr.conf cluster show
目標: 宕機的主庫重新加入集羣,並切回正式主庫
1. 重新加入集羣
repmgr -f $PGHOME/repmgr.conf node rejoin -d 'host=192.168.56.12 dbname=repmgr user=repmgr' --force-rewind --config-files=postgresql.conf,postgresql.auto.conf --verbose --dry-run
2. 查看是否成功加入集羣
repmgr -f /pg/pg11/repmgr.conf cluster show
3. 原主庫執行主備切換
repmgr -f /pg/pg11/repmgr.conf standby switchover --siblings-follow --force-rewind --log-level DEBUG --dry-run

本文內容就到這啦,閱讀完本篇,相信你對 PostgreSQL 高可用架構 repmgr 相關知識有了一定的認識了吧!我們下篇再見!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/PugdkU3B6qUdfrgyY79_aw