搭建基于流复制 PostgreSQL 主备虚拟机集群
概述
PostgreSQL 内置提供了基于流复制实现主备集群能力,使用场景:
- 防单点故障
- 读写分离提升 I/O 性能
流复制集群包含:
- 主节点 primary server:提供读写
- 备节点 standby server:提供只读查询;备节点在主故障时也可以提升为主
组成物理复制(physical replication)主备节点要求
select version()输出版本号为中major.minormajor 要一致,如15.1和15.2两个节点可以同步,14.1和15.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 地址块语法,不能是 IP10.0.0.2 - 应用权限配置,连接 pg 实例执行
SELECT pg_reload_conf();
- 按需修改 pg_hba.conf 设置权限
- 配置 pg_create_physical_replication_slot
在从节点或宿主机上执行,测试同步账号 PGPASSWORD="secret" psql -h 10.0.0.1 -p 5432 -U repl -d postgres
在主节点 pg 实例上执行,创建 replication slot
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`.bakprimary_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;
slot_name | slot_type | active | wal_status
-----------+-----------+--------+------------
repl01 | physical | t | reserved
(1 row)输出说明
slot_typeThe slot type: physical or logicalreservedmeans that the claimed files are within max_wal_size.activeTrue if this slot is currently actively being used
方法二:select * from pg_stat_replication;
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+08write_lag flush_lag replay_lag 三列字段如果为非空表示同步有延迟。
测试在主节点上插入新数据:
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)模式,只允许查数据不允许写入数据。
