Docker部署PostgreSQL主从

前置准备

创建 Docker 网络

因为只有一台机器,本例中主库和从库都部署在同一个机器中,为了主库和从库之间能通信,需要在同一个网络中固定主库和从库容器的 IP。

主库地址:172.12.0.2

从库地址:172.12.0.3

创建 Docker 网络:

# 创建
docker network create --driver bridge --subnet 172.12.0.0/16 --gateway 172.12.0.1 postgresqlnet

# 查看
docker network ls
docker network inspect postgresqlnet

数据库安装

拉取最新版 pg docker镜像:

docker pull postgres

启动容器:

# 主库
docker run -id --name=shorturl00 --network postgresqlnet --network-alias shorturl00 --ip 172.12.0.2 -v shorturl00:/var/lib/postgresql/data -p 5440:5440 -e POSTGRES_PASSWORD=12345678 -e LANG=C.UTF-8 postgres

# 从库
docker run -id --name=shorturl01 --network postgresqlnet --network-alias shorturl01 --ip 172.12.0.3 -v shorturl01:/var/lib/postgresql/data -p 5441:5441 -e POSTGRES_PASSWORD=12345678 -e LANG=C.UTF-8 postgres

查看容器运行情况:

docker ps -a

主库配置

因为没有使用默认的5432端口,先修改主库的连接端口为5440。进入主库容器,编辑 /var/lib/postgresql/data/postgresql.conf 文件:

port=5440

进入主库创建同步用户:

create role replicate with login password '12345678' replication;

返回 “CREATE ROLE” 表示创建成功。

修改文件 /var/lib/postgresql/data/pg_hba.conf 文件,修改 IPv4 和 replication 部分:

# IPv4 local connections:
host    all             all             0.0.0.0/0               trust

# replication privilege.
host    replication     all             0.0.0.0/0               trust

trust 表示不需要密码即可连接,不可用于生产环境!!

主库开启归档模式,在数据库中执行:

ALTER SYSTEM SET archive_command = ON ;
ALTER SYSTEM SET archive_command = 'cp -i %p /home/%f </dev/null';

完成以上配置,重启主库。

从库配置

进入从库容器先删除 /var/lib/postgresql/data 目录,然后进行首次同步,在终端执行:

pg_basebackup -h 172.12.0.2 -p 5440 -U replicate -w -Fp -Xs -Pv -R -D /var/lib/postgresql/data/ -l postgresqlbackup20240313

成功执行完之后,编辑从库 /var/lib/postgresql/data/postgresql.conf 文件,修改启动端口:

port=5441

设置从库 primary_conninfo:

ALTER SYSTEM SET  primary_conninfo = 'user=replicate host=172.12.0.2 port=5440 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any';

ALTER SYSTEM SET max_connections ='300';

配置完之后重启从库。

验证

在主库中增删数据,在从库中可以查询到数据变化。

踩坑记录

从库启动报错

报错信息:

2024-03-13 15:09:52.321 UTC [47] FATAL:  could not connect to the primary server: connection to server at "172.12.0.2", port 5400 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?

配置完从库 primary_conninfo 信息之后,从库重启报错提示无法连接 172.12.0.2:5400 ,后来排查发现是端口写错了,应该是5440才对,可以到 /var/lib/postgresql/data/postgresql.auto.conf 中修改这个配置,修改为正确的端口重启,该错误消失。

主库从库数据版本不一致

从库配置完之后重启报错:

2024-03-13 15:30:09.331 UTC [31] FATAL:  database system identifier differs between the primary and standby
2024-03-13 15:30:09.331 UTC [31] DETAIL:  The primary's identifier is 7344380814831386663, the standby's identifier is 7344385460223520808.

网上查资料发现是主库数据与从库数据不一致导致,从库初始化时删除 /var/lib/postgresql/data 目录。参考:docker搭建postgresql9.4主从同步复制集群

参考

Docker部署PostgreSQL主从