概要
组内项目使用 PostgreSQL,因为读写压力较大,决定先初步使用主从模式,主数据库写入,从库负责读取,从而降低单数据库压力,在网上找了一圈,发现中文互联网的教程较老,新版的 PostgreSQL 12 的配置方式已变更,recovery.conf
文件不再被支持,于是查阅资料,整理了基于 Docker 的 PostgreSQL 12 主从配置,新版本的配置非常简便,文末有一键部署脚本命令,可跳过文章直接使用
前置条件
- 准备两个 Linux 服务器(可使用虚拟机)
- 已经安装 Docker
本次测试部署主服务器IP:192.168.3.160,从库IP:192.168.3.135
首先,分别在两个服务器上创建 PostgreSQL 容器服务
docker run --name postgres --shm-size=512M -v /opt/pg-data/:/var/lib/postgresql/data/ --restart=unless-stopped -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres:latest
将数据库的数据目录映射到物理机的 /opt/pg-data 下,方便物理机访问
Master 配置
1,创建用于同步数据的用户
docker exec -it postgres /bin/sh -c "export PGPASSWORD=postgres && psql -U postgres -c \"CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'secret';\""
此处创建了名为 replicator 的用户,它的密码为 secret (直接使用 postgres 用户也是可以的但不推荐)
2,允许从库连接到主库
echo "host replication replicator 192.168.3.135/32 md5" >> /opt/pg_data/pg_hba.conf
3,重载配置
docker exec -it postgres /bin/sh -c "export PGPASSWORD=postgres && psql -U postgres -c \"select pg_reload_conf()\""
主库配置完成
Slave(Standby) 配置
1,移除所有从库数据文件
docker exec -it postgres /bin/sh -c "rm -rf /opt/pg-data/*"
删除从库数据目录下的所有文件,其目的是为同步主库做准备,否则同步数据时会发现主库与从库的校验不一致导致同步数据失败
2,复制主库基础数据
docker exec -it postgres /bin/sh -c "export PGPASSWORD=secret && pg_basebackup -h 192.168.3.160 -U replicator -p 5432 -D /var/lib/postgresql/data -Fp -Xs -P -R"
使用 pg_basebackup 工具来同步基础数据,参数 -R
会在数据目录下新建 standby.signal
文件,这个文件表示本数据库作为备份库存在,其只能读取,无法更新和写入,同样,设置了 -R
参数后,同步工具会自动添加配置信息,配置文件及内容如下
[root@centos7 ~]# cat /opt/pg-data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=replicator password=secret host=192.168.3.160 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'
primary_conninfo 保存着连接到主库同步数据的配置信息
使用 pg_basebackup 工具很方便,但你依然可以使用 scp 或 rsync 工具来将主库映射目录(/opt/pg-data/) 内的数据全部复制到从库的同目录下,然后使用 touch 命令手动创建 /opt/pg-data/standby.signal
文件,并手动编辑 postgresql.auto.conf 文件添加 primary_conninfo
信息
从库配置完成
检验部署
稍等片刻(5 ~ 10s),在主库所在机器上执行如下命令
docker exec -it postgres /bin/sh -c "export PGPASSWORD=postgres && psql -U postgres -x -c \"select * from pg_stat_replication\""
输出如下
-[ RECORD 1 ]----+------------------------------
pid | 286
usesysid | 16384
usename | replicator
application_name | walreceiver
client_addr | 192.168.3.135
client_hostname |
client_port | 39548
backend_start | 2019-12-26 06:00:41.067925+00
backend_xmin |
state | streaming
sent_lsn | 0/501AC48
write_lsn | 0/501AC48
flush_lsn | 0/501AC48
replay_lsn | 0/501AC48
write_lag |
flush_lag |
replay_lag |
sync_priority | 0
sync_state | async
reply_time | 2019-12-26 11:24:31.744954+00
有输出则代表主从数据库配置完成,可在主库修改数据,在从库查看变更
一键安装脚本
master_deploy.sh
#!/bin/bash
SLAVE_IP="192.168.3.135" # 填写从库服务器的IP
PGDATA="/opt/pg-data"
# 创建PostgreSQL容器
docker run --name postgres --shm-size=512M -v /opt/pg-data/:/var/lib/postgresql/data/ --restart=unless-stopped -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres:latest
# 休息5s等待容器启动完毕
sleep 5
# 创建用户
docker exec -it postgres /bin/sh -c "export PGPASSWORD=postgres && psql -U postgres -c \"CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'secret';\""
# 允许从数据库连接到master
echo "host replication replicator $SLAVE_IP/32 md5" >> $PGDATA/pg_hba.conf
# 重新载入配置
docker exec -it postgres /bin/sh -c "export PGPASSWORD=postgres && psql -U postgres -c \"select pg_reload_conf()\""
# 查询
#docker exec -it postgres /bin/sh -c "export PGPASSWORD=postgres && psql -U postgres -x -c \"select * from pg_stat_replication\""
slave_deploy.sh
#!/bin/bash
MASTER_IP="192.168.3.160" # 填写主库服务器的IP
PGDATA_OUT="/opt/pg-data"
PGDATA_IN="/var/lib/postgresql/data"
# 创建PostgreSQL容器
docker run --name postgres --shm-size=512M --net hylink -v /opt/pg-data/:/var/lib/postgresql/data/ --restart=unless-stopped -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres:latest
sleep 5
# 移除从数据库所有数据
docker exec -it postgres /bin/sh -c "rm -rf $PGDATA_IN/*"
# 同步数据(如果是新建的容器,则不用使用这个来同步数据,你可以使用任意方式rsync,scp来复制pgdata下的数据)
# 确保standby.signal文件的存在,pg_basebackup -R 会自动创建,也可以简单的使用touch创建
docker exec -it postgres /bin/sh -c "export PGPASSWORD=secret && pg_basebackup -h $MASTER_IP -U replicator -p 5432 -D $PGDATA_IN -Fp -Xs -P -R"
相较于之前的版本,PostgreSQL 12 进一步简化了配置,清晰且易于部署。
参考