前言
PostgreSQL的主从复制是一种非常简单且常用的高可用性和可扩展性解决方案,本质上是将主服务器的数据复制到一个或多个从服务器上,从而提高系统的性能和可靠性,并提供数据备份和故障恢复的能力。
环境准备
搭建主从节点
准备两个节点,一主一从,修改好ip,根据PostgreSQL 入门中的介绍安装好postgresql服务。
配置主从节点
先为主节点准备一些数据
create table t1 (id int);
insert into t1 values (111);
select * from t1;
接下来,主从都按照以下配置进行设置,因为后面会有主从切换的操作。
修改 pg_hba.conf 文件
修改 postgresql.conf 文件
提前构建好归档日志和备份目录,并且设置好拥有者
重启PostgreSQL服务
systemctl restart postgresql-12
从节点加入主节点
关闭从节点服务
systemctl stop postgresql-12
删除从节点数据(删除data目录)
rm -rf ~/12/data/*
基于pbk去主节点备份数据
# 确认好备份的路径,还有主节点的ip
pg_basebackup -D /pgbasebackup -Ft -Pv -Upostgres -h 192.168.10.10 -p 5432 -R
恢复数据操作,解压tar包
cd /pgbasebackuo
tar -xf base.tar -C ~/12/data
tar -xf pg_wal.tar -C /archive
修改postgresql.auto.conf文件
# 确认有这两个配置,一般第一个需要手写,第二个会自动生成
restore_command = 'cp /archive/%f %p'
primary_conninfo = 'user=postgres password=postgres host=192.168.10.10 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'
修改standby.signal文件,开启从节点备份模式
# 开启从节点备份
standby_mode = 'on'
启动从节点服务
systemctl restart postgresql-12
查看主从信息
- 查看从节点是否有t1表
- 主节点添加一行数据,从节点再查询,可以看到最新的数据
- 从节点无法完成写操作,他是只读模式
- 主节点查看从节点信息
select * from pg_stat_replication
- 从节点查看主节点信息
select * from pg_stat_wal_receiver
主从故障切换
PostgreSQL自身只支持简单的主从,不提供主从自动切换,如果要实现此功能只能通过Nginx这样的负载并采用keepalived的形式,在主节点宕机后,通过脚本的执行完成主从切换,这里做一个手动的故障切换操作。
默认情况下,主从备份是异步的,这样会导致一个问题:如果主节点写入的数据还没有备份到从节点,主节点忽然宕机了,数据可能丢失。
PGSQL在9.5版本后提供了一个pg_rewind的操作,基于归档日志做一个比对,是否有时间差冲突。
操作步骤:
-
rewind需要开启一项配置才可以使用
修改postgresql.conf中的 wal_log_hints = ‘on’ -
为了可以更方便的使用rewind,需要设置一下 /usr/pgsql-12/bin/ 的环境变量
vi /etc/profile 追加信息 export PATH=/usr/pgsql-12/bin/:$PATH source /etc/profile
-
模拟主库宕机,直接对主库关机。
-
从节点切换为主节点
# 默认会去找$PGDATA,如果没有配置,基于-D指定一下PGSQL的data目录 pg_ctl promote -D ~/12/data/
-
将原主节点开机,执行归档日志的同步。
- 停止PGSQL服务
pg_ctl stop -D ~/12/data
- 基于pg_rewind加入到集群
pg_rewind -D ~/12/data/ --source-server='host=192.168.10.10 user=postgres password=postgres'
- 如果上述命令失败,需要再执行以上操作。
- 停止PGSQL服务
-
修改原主节点(新从节点)的配置
- 构建standby.signal
standby_mode = 'on'
- 修改postgresql.auto.conf文件
# 注意ip地址 primary_conninfo = 'user=postgres password=postgres host=192.168.10.10 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any' restore_command = 'cp /archive/%f %p'
- 启动新的从节点
pg_ctl start -D ~/12/data/
- 构建standby.signal