PostgreSQL 高可用 Stream

1 背景知识

本文主要介绍如何搭建 PostgreSQL 主备流复制。

主要参考 流复制 章节。

2 环境信息

主机名称 IP地址 FDW 角色
node1 192.168.10.232 master
node2 192.168.10.233 standby
node3 192.168.10.234 standby

3 前提条件

3.1 安装数据库

请参考 PostgreSQL15 文章,并安装数据库,安装好之后复制虚拟机为node1,node2,node3 三个节点。并按照下面邀请清空 /data 目录。

Warning

恢复到快照:DB_INSTALL
node1 完成数据库安装。
node2 完成软件安装。未初始化data。
node3 完成软件安装。未初始化data。

3.2 配置DNS 解析

node1、node2、node3

#root#
cat >> /etc/hosts << EOF
192.168.10.236 node1
192.168.10.237 node2
192.168.10.238 node3
EOF

4 搭建异步(async)流复制环境

4.1 配置主库node1 流复制环境

4.1.1 配置流复制用户

testdb#
CREATE ROLE repl LOGIN REPLICATION  PASSWORD 'repl';

4.1.2 配置pg_hba 客户端认证文件

postgres> vi $PGDATA/pg_hba.conf
--------------------input------------------------------
host    replication     repl            192.168.10.0/24         trust

4.1.3 配置数据库参数

1、 创建归档目录。

postgres> mkdir -p /home/postgres/arch/

2、配置数据库相关参数。

psqlgres>
cat >> $PGDATA/repl.conf << EOF
wal_log_hints=on
wal_level = replica             # minimal, replica, or logical
max_wal_senders = 10            # max number of walsender processes
max_replication_slots = 10
wal_keep_segments = 1024	# in logfile segments, 16MB each; 0 disables 
hot_standby = on
synchronous_commit = on
synchronous_standby_names = '1(node1,node2,node3)'
hot_standby_feedback=on
fsync=on
# for archive log
archive_mode = on
archive_command = 'cp %p /home/postgres/arch/%f'
EOF

cat >> $PGDATA/postgresql.conf << EOF
include_if_exists='repl.conf'
EOF

3、重启数据库生效

pg_ctl restart -D $PGDATA

4、创建复制槽

psqlgres> psql -U repl -d testdb
SELECT * FROM pg_create_physical_replication_slot('slot_node2'); 
SELECT * FROM pg_create_physical_replication_slot('slot_node3'); 
SELECT slot_name, slot_type, active FROM pg_replication_slots;

5、配置error log 日志。
具体操作请参考 配置Error log

4.2 配置备库node2流复制环境

4.2.1 存量数据传输

pg_basebackup -h node1 -p 1922 -U repl -S slot_node2 -Fp -X stream -v -P -R -D   $PGDATA
ls -lh /data
du -sh /data
Warning

使用了-R 选项,会自动在postgresql.auto.conf 里创建恢复参数

4.2.2 查看配置是否正确。

cat $PGDATA/postgresql.auto.conf 

4.2.3 启动备库并开启流复制

pg_ctl start -D $PGDATA
tail -f $PGDATA/pg_log/postgresql*.csv

4.3 配置备库node3流复制环境

4.3.1 存量数据传输

pg_basebackup -h node1 -p 1922 -U repl -S slot_node3 -Fp -X stream -v -P -R -D   $PGDATA
Warning

使用了-R 选项,会自动在postgresql.auto.conf 里创建恢复参数

4.3.2 查看配置是否正确。

cat $PGDATA/postgresql.auto.conf 

4.3.3 启动备库并开启流复制

pg_ctl start -D $PGDATA
tail -f $PGDATA/pg_log/postgresql*.csv

4.4 查看流复制状态

SELECT * FROM pg_stat_replication;
Warning

注意:现在是异步同步状态,需要配置 application_name=node3 才能进入同步状态

4.5 验证同步

创建一张表,验证其他数据库是否同步。

CREATE TABLE t01(id int);

5 配置同步(sync)流复制环境

5.1 配置备库node2流复制环境

1、修改参数

postgres> vi $PGDATA/postgresql.auto.conf 
--------------------input------------------------------
primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' host=node1 port=1922 application_name=node2 sslmode=disable sslcompression=0 gssencmod
e=disable krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_node2'
Warning

添加application_name=node2 参数。
2、重启备库

pg_ctl restart -D $PGDATA

5.2 配置备库node3流复制环境

postgres> vi $PGDATA/postgresql.auto.conf 
--------------------input------------------------------
primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' host=node1 port=1922 application_name=node3 sslmode=disable sslcompression=0 gssencmod
e=disable krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_node2'
Warning

添加application_name=node3 参数。

2、重启备库

pg_ctl restart -D $PGDATA

5.3 查看流复制状态

SELECT * FROM pg_stat_replication;
Warning

注意:现在是同步状态,一个为sync 同步备库,一个为async 异步备库。

5.4 验证同步

创建一张表,验证其他数据库是否同步。

CREATE TABLE t01(id int);

6 流复制健康状态检查

6.1 查看数据库状态

1、查看状态

select pg_is_in_recovery();

2、查看进程

ps -ef|grep -v grep|grep -E 'sender|receiver'

3、查看控制文件

pg_controldata -D $PGDATA | grep -E '状态|state'

4、查看standby.single文件

find $PGDATA -name standby.signal

6.2 查看流复制状态

SELECT * FROM pg_stat_replication;
Warning

注意:现在是异步同步状态,需要配置 application_name=node3 才能进入同步状态

6.3 查看复制槽状态

SELECT * FROM pg_replication_slots;

7 三节点主备切换

7.1 Node 1 准备

1、确认主库相关信息

postgres> psql -U postgres -d testdb
pg_controldata -D /data | grep -E '状态|state'
find /data -name standby.signal
ps -ef | grep -v grep | grep -E 'sender|receiver'
ksql -Usystem -dtest
\x
SELECT * FROM pg_stat_replication;
SELECT pg_is_in_recovery();

1、关闭node1

pg_ctl stop -D $PGDATA

2、主节点停机后备节点信息

cd $PGDATA/pg_log
tail -n5  `ls -lrt $PGDATA/pg_log|tail -1|awk '{print $NF}'`

7.2 Node2成为主节点

1、备变主

pg_ctl promote -D $PGDATA

2、查看Node2 信息

pg_controldata -D $PGDATA |grep -E '状态|state'
find $PGDATA -name standby.signal
ps -ef|grep -v grep|grep -E 'sender|receiver'

3、创建复制槽

psql -h node2 -p 1922 -U repl -d testdb
SELECT slot_name, slot_type, active FROM pg_replication_slots;  
SELECT * FROM pg_create_physical_replication_slot('slot_node1');
SELECT * FROM pg_create_physical_replication_slot('slot_node3');
SELECT slot_name, slot_type, active FROM pg_replication_slots; 
\! ps -ef|grep -v grep|grep -E 'sender|receiver'

7.3 Node1 成为备库

1、创建standby.signal

touch $PGDATA/standby.signal

2、配置参数

cat >> $PGDATA/postgresql.auto.conf << EOF
primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' host=node2 port=1922 application_name=node1 sslmode=disable sslcompression=0 gssencmode=disable krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_node1'
EOF

3、 启动该节点

$ pg_ctl start -D $PGDATA

4、主变备后信息

pg_controldata -D $PGDATA |grep -E '状态|state'
find $PGDATA -name standby.signal
ps -ef|grep -v grep|grep -E 'sender|receiver'

7.4 Node3 流复制重定向

1、停止备库Node3

pg_ctl stop -D $PGDATA

2、配置参数

vi $PGDATA/postgresql.auto.conf
--------------------input------------------------------
primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' host=node2 port=1922 application_name=node3 sslmode=disable sslcompression=0 gssencmode=disable krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_node3'

3、 启动该节点

pg_ctl start -D $PGDATA

4、主变备后信息

pg_controldata -D $PGDATA |grep -E '状态|state'
find $PGDATA -name standby.signal
ps -ef|grep -v grep|grep -E 'sender|receiver'

7.5 验证同步

创建一张表,验证其他数据库是否同步。

CREATE TABLE t01(id int);

8 参数解释

synchronous_standby_names
选项 说明
ALL
ANY qourum

9 延迟复制

recov...
Client
Client
primary 
database
primary...
standby
database
standby...
standby
database
standby...
Client
Client
同步
同步
延迟同步
延迟同步
Client
Client
commi...

Viewer does not support full SVG 1.1
postgres> psql -U repl -d testdb
ALTER SYSTEM SET recovery_min_apply_delay=120000;

10 小结 & FAQ

这里有 3节点流复制2节点流复制 多种方案,可以根据自己的需求进行搭建。