PG12高可用之1主2从流复制环境搭建及切换测试
PG12高可用之1主2从流复制环境搭建及切换测试

一、架构介绍
1.1、流复制简介
PostgreSQL在9.x之后引入了主从的流复制机制,所谓流复制,就是备服务器通过tcp流从主服务器中同步相应的数据,主服务器在WAL记录产生时即将它们以流式传送给备服务器,而不必等到WAL文件被填充。
流复制属于物理层面的复制,可以从实例级复制出一个与主库一模一样的实例级的从库,流复制同步方式有同步、异步两种。
-
异步流复制模式中,主库提交的事务不会等待备库接收WAL日志流并返回确认信息,因此异步流复制模式下主库与备库的数据版本上会存在一定的处理延迟(毫秒级),当主库宕机,这个延迟就主要受到故障发现与切换时间的影响而拉长。该模式为默认模式。
-
同步流复制模式中,要求主库把WAL日志写入磁盘,同时等待WAL日志记录复制到备库、并且WAL日志记录在任意一个备库写入磁盘后,才能向应用返回Commit结果。一旦所有备库故障,在主库的应用操作则会被挂起,所以此方式建议起码是1主2备。
物理复制优点∶
√物理层面完全一致,是主要的复制方式,其类似于Oracle的DG。
√延迟低,事务执行过程中产生REDO record,实时的在备库apply,事务结束时,备库立马能见到数据。
√物理复制的一致性、可靠性高,不必担心数据逻辑层面不一致。
物理复制缺点︰
√无法满足不同的版本之间、不同库名之间的表同步。
√无法满足指定库或部分表的复制需求
√无法满足将多个数据库实例同步到一个库,将一个库的数据分发到多个不同的库。
物理复制场景:
√适合于单向同步。
√适合于任意事务,任意密度写(重度写)的同步。√适合于HA、容灾、读写分离。
√适合于备库没有写,只有读的场景。
物理复制原理︰
√PG主备流复制的核心部分由walsender , walreceiver和startup三个进程组成。
√ walsender进程是用来发送WAL日志记录的,用于主库发送WAL日志记录至从库
√ walreceiver进程是用来接收WAL日志记录的,用于从库接收主库的WAL日志记录
√ startup进程用于从库apply日志
物理流复制的过程如下所示:

1.2、本文目标
1、先搭建1主1从异步模式,测试主从同步,再进行主从切换
2、再添加一个从库,变为1主2从
3、同步模式和异步模式相互切换
1主1从环境架构如下:

二、环境准备
-- 拉取镜像
docker pull postgres:12
-- 创建PG高可用环境专用网络
docker network create --subnet=172.72.6.0/24 pg-network
-- 创建宿主机相关映射路径
mkdir -p /docker_data/pg/lhrpg64302/data
mkdir -p /docker_data/pg/lhrpg64303/data
-- 主库
docker rm -f lhrpg64302
rm -rf /docker_data/pg/lhrpg64302/data
docker run -d --name lhrpg64302 -h lhrpg64302 \
-p 64302:5432 --net=pg-network --ip 172.72.6.2 \
-v /docker_data/pg/lhrpg64302/data:/var/lib/postgresql/data \
-v /docker_data/pg/lhrpg64302/bk:/bk \
-e POSTGRES_PASSWORD=lhr \
-e TZ=Asia/Shanghai \
postgres:12
-- 从库
docker rm -f lhrpg64303
rm -rf /docker_data/pg/lhrpg64303/data
rm -rf /docker_data/pg/lhrpg64303/bk
docker run -d --name lhrpg64303 -h lhrpg64303 \
-p 64303:5432 --net=pg-network --ip 172.72.6.3 \
-v /docker_data/pg/lhrpg64303/data:/var/lib/postgresql/data \
-v /docker_data/pg/lhrpg64303/bk:/bk \
-e POSTGRES_PASSWORD=lhr \
-e TZ=Asia/Shanghai \
postgres:12
-- 远程登录
psql -U postgres -h 192.168.66.35 -p 64302
psql -U postgres -h 192.168.66.35 -p 64303
三、主库操作
3.1、主库放开防火墙
cat << EOF > /docker_data/pg/lhrpg64302/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 trust
host all all 0.0.0.0/0 md5
host replication all 0.0.0.0/0 md5
EOF
👉 注意添加replication
3.2、主库配置归档
-- 登陆主库环境
docker exec -it lhrpg64302 bash
-- 该路径也需要在从库创建
mkdir -p /postgresql/archive
chown -R postgres.postgres /postgresql/archive
-- 修改参数
cat >> /var/lib/postgresql/data/postgresql.conf <<"EOF"
wal_level='replica'
archive_mode='on'
archive_command='test ! -f /postgresql/archive/%f && cp %p /postgresql/archive/%f'
max_wal_senders=10
wal_keep_segments=256
wal_sender_timeout=60s
EOF
-- 重启主库
docker restart lhrpg64302
-- 或:
/usr/lib/postgresql/12/bin/pg_ctl restart -D /var/lib/postgresql/data/
-- 查询参数
psql -U postgres -h 192.168.66.35 -p 64302
select * from pg_settings where name in ('wal_level','archive_mode','archive_command');
-- 切换归档
select pg_switch_wal();
执行结果:
postgres=# select * from pg_settings where name in ('wal_level','archive_mode','archive_command');
name | setting | unit | category | short_desc | extra_desc | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | sourcefile | sourceline | pending_restart
-----------------+------------------------------------------------------------------+------+-----------------------------+-------------------------------------------------------------------+------------+------------+---------+--------------------+---------+---------+---------------------------+----------+------------------------------------------------------------------+------------------------------------------+------------+-----------------
archive_command | test ! -f /postgresql/archive/%f && cp %p /postgresql/archive/%f | | Write-Ahead Log / Archiving | Sets the shell command that will be called to archive a WAL file. | | sighup | string | configuration file | | | | | test ! -f /postgresql/archive/%f && cp %p /postgresql/archive/%f | /var/lib/postgresql/data/postgresql.conf | 753 | f
archive_mode | on | | Write-Ahead Log / Archiving | Allows archiving of WAL files using archive_command. | | postmaster | enum | configuration file | | | {always,on,off} | off | on | /var/lib/postgresql/data/postgresql.conf | 752 | f
wal_level | replica | | Write-Ahead Log / Settings | Set the level of information written to the WAL. | | postmaster | enum | configuration file | | | {minimal,replica,logical} | replica | replica | /var/lib/postgresql/data/postgresql.conf | 751 | f
(3 rows)
postgres=# select * from pg_stat_get_archiver();
-[ RECORD 1 ]------+-----------------------------------------
archived_count | 8
last_archived_wal | 000000010000000000000006.00000028.backup
last_archived_time | 2021-04-22 11:42:54.049649+00
failed_count | 0
last_failed_wal |
last_failed_time |
stats_reset | 2021-04-22 11:35:55.727069+00
postgres=# select pg_switch_wal();
-[ RECORD 1 ]-+----------
pg_switch_wal | 0/7015058
postgres=# select * from pg_stat_get_archiver();
-[ RECORD 1 ]------+------------------------------
archived_count | 9
last_archived_wal | 000000010000000000000007
last_archived_time | 2021-04-23 01:00:30.076916+00
failed_count | 0
last_failed_wal |
last_failed_time |
stats_reset | 2021-04-22 11:35:55.727069+

