PostgreSQL10基于stream复制搭建主从集群

说明

这里只记录搭建和简单测试过程

不保证ctrl+cctrl+v能完整跑起来

操作系统使用的CentOS-7.6.1810 x86_64

PostgreSQL版本号10.8

虚拟机配置1CPU 2G内存 20G系统盘

postgres用户默认情况下PGDATA变量是/var/lib/pgsql/10/data

这里没有使用数据盘,有需要的可以自行调整!

环境准备

主机清单

主机名IP地址角色监听端口
pg1172.16.80.201master5432
pg2172.16.80.202slave5432

配置/etc/hosts

1
2
3
4
5
cat > /etc/hosts <<EOF
127.0.0.1 localhost
172.16.80.201 pg1
172.16.80.202 pg2
EOF

安装PostgreSQL

参照此链接在两个节点上面安装好PostgreSQL,但是先不初始化数据库!!!!

PostgreSQL10安装部署和初始化

基于stream主从复制配置

master节点

创建数据库

如果是有业务在跑,已经有数据了就不要做这一步操作!直接从创建复制用户那一步开始
1
/usr/pgsql-10/bin/postgresql-10-setup initdb

启动数据库

1
systemctl enable --now postgres-10.service

登录数据库

1
psql -U postgres

创建复制用户

1
CREATE USER repluser REPLICATION LOGIN CONNECTION LIMIT 2 ENCRYPTED PASSWORD 'repluser_password';

创建.pgpass文件

1
2
3
4
5
su - postgres
cat > ~/.pgpass <<EOF
pg2:5432:replication:repluser:repluser_password
EOF
chmod 0600 ~/.pgpass

编辑pg_hba.conf

增加配置如下

1
host    replication     repluser        172.16.80.0/24          md5

编辑postgres.conf

增加配置参数如下

1
2
3
4
5
6
7
8
9
10
wal_level = replica
# 有多少个slave节点,max_wal_senders就设置为多少
max_wal_senders = 1
# wal_keep_segments可以设置大一点,每个segments大小16MB
# 这样在备库不会因为wal receiver启动太慢导致所需wal在主库被删除
wal_keep_segments = 64
# 加上这个synchronous_standby_names可以开启同步复制
# 从库不在线或者无法执行写操作时,本地执行完之后会卡住无法返回写入成功
# 请自行斟酌之后再决定是否配置同步复制
# synchronous_standby_names = 'pg2'

重启数据库

1
2
su - postgresql
/usr/pgsql-10/bin/pg_ctl restart -D $PGDATA

slave节点

创建.pgpass文件

1
2
3
4
5
su - postgres
cat > ~/.pgpass <<EOF
pg1:5432:replication:repluser:repluser_password
EOF
chmod 0600 ~/.pgpass

pg_basebackup生成备库文件

把master节点的数据以物理备份的方式,保存到slave节点。

备份过程不影响其他客户端访问。

备份出来的内容是整个数据库的所有数据,包括配置文件!

  • -D指定PostgreSQL数据目录
  • -Fp指定输出格式为plain,这里是缩写,相当于--format=plain
  • -Xs指定传输WAL日志的方法为stream,这里是缩写,相当于--wal-method=stream
  • -h指定PostgreSQL master节点
  • -p指定端口
  • -U指定用户
1
2
su - postgres
pg_basebackup -D $PGDATA -Fp -Xs -v -P -h pg1 -p 5432 -U repluser

配置recovery.conf

从master节点拷贝过来的数据文件是没有recovery.conf

需要手动创建

好在PostgreSQL安装的时候是有这个配置文件的模板

里面都是注释

1
2
su - postgres
cp /usr/pgsql-10/share/recovery.conf.sample $PGDATA/recovery.conf

修改之后,内容如下

1
2
3
4
5
6
7
8
9
10
# 指定timeline为latest,保证主从数据差异尽可能小
recovery_target_timeline = 'latest'
# 此选项会让PostgreSQL一直处于数据恢复状态
# 不断去请求primary_conninfo定义的主节点的WAL日志
# 并将这些WAL日志恢复到本地数据库中
standby_mode = on
# 定义主库的连接方式
primary_conninfo = 'host=pg1 port=5432 user=repluser password=repluser_password application_name=pg2'
# 这个文件是用于触发停止流复制的操作!不需要手动创建
trigger_file = '/var/lib/pgsql/10/data/pg.trigger'

启动备库

1
systemctl enable --now postgresql-10.service

验证

master节点

查看进程

1
ps -ef | grep postgres

查看是否有postgres: wal sender process

查看recovery状态

登录数据库

1
psql -U postgres -h pg1

输入sql语句,主库返回f

1
2
3
4
5
postgres=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
f
(1 row)

查看主备同步状态

登录数据库

1
psql -U postgres -h pg1

修改一下输出格式,将每列数据以键值对的方式显示,类似于MySQL的\G

这里是输入一次,当前会话有效,想取消就再输入一次

1
\x

查看同步状态

这里可以看到sync_stateasync,即异步流复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
postgres=# select * from pg_stat_replication ;
-[ RECORD 1 ]----+------------------------------
pid | 8154
usesysid | 16384
usename | repluser
application_name | pg2
client_addr | 172.16.80.202
client_hostname |
client_port | 17024
backend_start | YYYY-MM-DD HH:mm:ss.800271+08
backend_xmin |
state | streaming
sent_lsn | 0/3000108
write_lsn | 0/3000108
flush_lsn | 0/3000108
replay_lsn | 0/3000108
write_lag |
flush_lag |
replay_lag |
sync_priority | 1
sync_state | async

slave节点

查看进程

1
ps -ef | grep postgres

查看是否有postgres: wal receiver process

查看recovery状态

登录数据库

1
psql -U postgres -h pg2

输入sql语句,从库返回t

1
2
3
4
5
postgres=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
t
(1 row)