Skip to content

搭建基于流复制 PostgreSQL 主备虚拟机集群

概述

PostgreSQL 内置提供了基于流复制实现主备集群能力,使用场景:

  • 防单点故障
  • 读写分离提升 I/O 性能

流复制集群包含:

  • 主节点 primary server:提供读写
  • 备节点 standby server:提供只读查询;备节点在主故障时也可以提升为主

组成物理复制(physical replication)主备节点要求

  • select version() 输出版本号为中 major.minor major 要一致,如 15.115.2 两个节点可以同步,14.115.1 不可以
  • 节点机器同架构,32 位和 32 位可以,64 位和 64 位可以,32 和 64 位不可以。

注:如果想不同版本和架构节点间同步,需用 Logical Replication (逻辑复制) .

工作原理:TBD.

后面以虚拟机环境搭建为例:

  • Ubuntu LTS
  • PostgreSQL 14-16
  • 主节点主机 ip 10.0.0.1
  • 备节点主机 ip 10.0.0.2

创建主节点

安装 PostgreSQL 包 sudo apt install postgresql

TBD。

设置主节点集群相关配置

在主节点 上执行

  • 创建同步账户 repl CREATE ROLE repl login replication encrypted password 'secret';
  • 配置 主机访问权限,修改 iptables
  • 配置 postgres 访问权限,修改配置文件 /etc/postgresql/16/main/pg_hba.conf
    • 按需修改 pg_hba.conf 设置权限 host replication repl 10.0.0.2/32 md5 ,注意:主机部分 10.0.0.2/32 必须是 CIDR 地址块语法,不能是 IP 10.0.0.2
    • 应用权限配置,连接 pg 实例执行 SELECT pg_reload_conf();
  • 配置 pg_create_physical_replication_slot

在从节点或宿主机上执行,测试同步账号 PGPASSWORD="secret" psql -h 10.0.0.1 -p 5432 -U repl -d postgres

在主节点 pg 实例上执行,创建 replication slot

sql
select * from pg_create_physical_replication_slot('repl01');
select slot_name, slot_type, active, wal_status from pg_replication_slots;

注:slot 不支持改名,可重建 select * from pg_drop_replication_slot('repl01');

创建备节点

在备节点上执行

安装 PostgreSQL 包 sudo apt install postgresql

在从上同步主数据:

sudo bash

/etc/init.d/postgresql stop

mv /var/lib/postgresql/16/main /var/lib/postgresql/16/main-`date +%Y%m%d`.bak

PGPASSWORD=secret \
pg_basebackup \
--pgdata /var/lib/postgresql/16/main \
 --verbose \
--format=p \
--write-recovery-conf \
--checkpoint=fast \
--label=mffb \
--progress \
--host=10.0.0.1 \
--port=5432 \
--username=repl

如果备节点无法访问主节点,留意主节点日志 /var/log/postgresql/postgresql-14-main.log 错误提示,按需修改 主认证配置文件 /etc/postgresql/16/main/pg_hba.conf。

示例提示错误:

2049-05-19 09:06:24.100 GMT [153] FATAL: no pg_hba.conf entry for replication connection from host "172.1.2.3", user "repl", no encryption

则修改住认证配置文件 pg_hba.conf ,补 host replication repl 172.1.2.3/32 md5

修改备节点主要配置 postgresql.conf 和认证配置文件 pg_hba.conf ,两个文件内容可参考主节点。

修改主要配置文件 /etc/postgresql/16/main/postgresql.conf

cp /etc/postgresql/16/main/postgresql.conf /etc/postgresql/16/main/postgresql.conf-`date +%Y%m%d`.bak
txt
primary_conninfo = 'user=repl port=5432 host=10.0.0.1 password=secret'
primary_slot_name = 'repl01'

listen_addresses = '*'

logging_collector = on

# 所有日志写到 /var/log/postgresql/ 目录下
log_directory = '/var/log/postgresql'

log_min_messages = info
log_min_duration_statement = 500

修改认证配置文件 /etc/postgresql/16/main/pg_hba.conf

修正目录权限 chown -R postgres:postgres /var/lib/postgresql/16/main

重启 postgresql 进程

另开一终端,连接主节点上执行确认复制状态。

方法一:select slot_name, slot_type, active, wal_status from pg_replication_slots;

txt
 slot_name | slot_type | active | wal_status
-----------+-----------+--------+------------
 repl01    | physical  | t      | reserved
(1 row)

输出说明

  • slot_type The slot type: physical or logical
  • reserved means that the claimed files are within max_wal_size.
  • active True if this slot is currently actively being used

方法二:select * from pg_stat_replication;

txt
pid              | 3714690
usesysid         | 16505
usename          | repl
application_name | 14/main
client_addr      | 10.0.0.2
client_hostname  |
client_port      | 47772
backend_start    | 2049-01-23 20:13:24.429329+08
backend_xmin     |
state            | streaming
sent_lsn         | 4B/E8080518
write_lsn        | 4B/E8080518
flush_lsn        | 4B/E8080518
replay_lsn       | 4B/E8080518
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 0
sync_state       | async
reply_time       | 2049-01-23 20:28:07.26646+08

write_lag flush_lag replay_lag 三列字段如果为非空表示同步有延迟。

测试在主节点上插入新数据:

sql
create table t1 (id int) ;
insert into t1 (id) values (1);

在备上查询

备会自动从主复制认证配置,使用主的账号密码然后替换掉主机(-h)参数链接 PGPASSWORD="secret" psql -h 10.0.0.2 -U somebody -p 5432 -d d1 ; 查询 d1 库 t1 表确认数据同步:select * from t1;

注:默认备节点是只读(read-only)模式,只允许查数据不允许写入数据。

参考

Released under the CC-BY-NC-4.0