原 【DB宝60】PG12高可用之1主2从流复制环境搭建及切换测试
[toc]
一、架构介绍
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从环境架构如下:
二、环境准备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | -- 拉取镜像 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、主库放开防火墙
1 2 3 4 5 6 7 8 | 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、主库配置归档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | -- 登陆主库环境 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(); |
执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 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+00 -- 切换归档前 root@lhrpg64302:/# ps -ef|grep post postgres 1 0 0 01:28 ? 00:00:00 postgres postgres 26 1 0 01:28 ? 00:00:00 postgres: checkpointer postgres 27 1 0 01:28 ? 00:00:00 postgres: background writer postgres 28 1 0 01:28 ? 00:00:00 postgres: walwriter postgres 29 1 0 01:28 ? 00:00:00 postgres: autovacuum launcher postgres 30 1 0 01:28 ? 00:00:00 postgres: archiver postgres 31 1 0 01:28 ? 00:00:00 postgres: stats collector postgres 32 1 0 01:28 ? 00:00:00 postgres: logical replication launcher postgres 33 1 0 01:29 ? 00:00:00 postgres: postgres postgres 172.72.6.1(6884) idle root 40 34 0 01:29 pts/0 00:00:00 grep post root@lhrpg64302:/# cd /postgresql/archive/ root@lhrpg64302:/postgresql/archive# ls -l total 0 -- 切换归档 postgres=# select pg_switch_wal(); pg_switch_wal --------------- 0/1645528 (1 row) -- 切换归档后 root@lhrpg64302:/postgresql/archive# ls -l total 16384 -rw------- 1 postgres postgres 16777216 Apr 23 01:30 000000010000000000000001 root@lhrpg64302:/postgresql/archive# ps -ef|grep post postgres 1 0 0 01:28 ? 00:00:00 postgres postgres 26 1 0 01:28 ? 00:00:00 postgres: checkpointer postgres 27 1 0 01:28 ? 00:00:00 postgres: background writer postgres 28 1 0 01:28 ? 00:00:00 postgres: walwriter postgres 29 1 0 01:28 ? 00:00:00 postgres: autovacuum launcher postgres 30 1 0 01:28 ? 00:00:00 postgres: archiver last was 000000010000000000000001 postgres 31 1 0 01:28 ? 00:00:00 postgres: stats collector postgres 32 1 0 01:28 ? 00:00:00 postgres: logical replication launcher postgres 33 1 0 01:29 ? 00:00:00 postgres: postgres postgres 172.72.6.1(6884) idle root 47 34 0 01:30 pts/0 00:00:00 grep post |
- 参数max_wal_senders介绍:
Specifies the maximum number of concurrent connections from standby servers or streaming base backup clients (i.e., the maximum number of simultaneously running WAL sender processes). The default is zero, meaning replication is disabled. WAL sender processes count towards the total number of connections, so the parameter cannot be set higher than max_connections. This parameter can only be set at server start. wal_level must be set to archive or hot_standby to allow connections from standby servers.
也就是说,这个参数是在主机上设置的,是从机连接到主机的并发连接数之总和,所以这个参数是个正整型。默认值是0,也即默认没有流复制功能。该并发连接数从进程上看,就是各个wal sender进程数之和,可以通过ps -ef|grep senders来查看,所以该值不能超过系统的最大连接数(max_connections,该BUG在9.1.5被修复),可以允许超过实际的流复制用户数。该参数更改需要重启DB,比如我只配了一个从机:
[postgres@ndb2 database]$ ps -ef|grep sender
postgres 21257 21247 0 20:57 ? 00:00:00 postgres: wal sender process repuser 192.25.10.71(46161) streaming 0/4018ED8
postgres 22193 20949 0 23:02 pts/0 00:00:00 grep sender
- 参数wal_keep_segments=256介绍
表示保留多少个WAL文件。如果源库业务较繁忙,那么应该相应的增加这个值。
在PG13中,wal_keep_segments 已经取消,改用 wal_keep_size
- 参数wal_sender_timeout=60s介绍
中断那些停止活动超过指定毫秒数的复制连接。这对发送服务器检测一个后备机崩溃或网络中断有用。设置为0将禁用该超时机制。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。默认值是 60 秒。
3.3、主库创建复制用户
1 | create role replhr login encrypted password 'lhr' replication; |
? 创建用户需要加上replication选项。
四、从库操作
4.1、在从库对主库进行备份
1 2 3 4 5 6 7 8 | docker exec -it lhrpg64303 bash mkdir -p /bk chown postgres:postgres /bk su - postgres pg_basebackup -h 172.72.6.2 -p 5432 -U replhr -l bk20210422 -F p -P -R -D /bk |
1 条回复
[…] 【DB宝60】PG12高可用之1主2从流复制环境搭建及切换测试 […]