利用Docker部署PostgreSQL 12.4主从方式
作者:Expect-乐
这篇文章主要介绍了利用Docker部署PostgreSQL 12.4主从方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
通过Docker部署PG主从
主要用于测试,通过 Docker 快速部署 PG 主从。
环境架构
基于PG 12.4 版本安装
IP | 角色 |
---|---|
172.18.12.100 | 主 |
172.18.12.101 | 从 |
部署
下载镜像,运行容器,配置主从。
步骤1:下载镜像
[root@lei ~]# docker pull postgres:12.4-alpine
官方镜像地址:https://hub.docker.com/_/postgres?tab=description
可根据自己需要下载其他版本的 PG。
步骤2:配置网络
在开始之前需要为每个容器指定一个IP,虽然不指定也可以,当时IP可能 会随时变动导致 PG 主从复制失败。
所以最好手动为每个容器指定一个IP地址。
创建网络
docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.12.1 mynet
查看当前网络配置
[root@lei ~]# docker inspect mynet [ { "Name": "mynet", "Id": "9bcbf9f08168af8ee61f766014629bce6adbe11e00842f53ab2bc84615ddc2e2", "Created": "2020-11-09T16:01:03.276711818+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.12.0/16", "Gateway": "172.18.12.1" } ] }, "Internal": false, "Attachable": false, "Containers": {}, "Options": {}, "Labels": {} } ]
注意:指定IP地址,只能自定义网络。
步骤3:运行容器
通过指定端口映射,目录映射,容器名,IP地址运行容器。
- 主
[root@lei ~]# mkdir -p /home/pg_p/data [root@lei ~]# docker run --name pg_p --restart=always --network=mynet --ip 172.18.12.100 -v /home/pg_p/data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=123456 -p 5432:5432 -d postgres:12.4-alpine
- 从
[root@lei ~]# mkdir -p /home/pg_s/data [root@lei ~]# docker run --name pg_s --restart=always --network=mynet --ip 172.18.12.101 -v /home/pg_s/data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=123456 -p 5433:5432 -d postgres:12.4-alpine
参数说明:
- –name:指定容器名,随便写
- –restart=always:表示容器随着docker进程自动启动
- –network,–ip:容器指定IP
- -v :将容器内的目录映射(/var/lib/postgresql/data)到本机目录(/home/pg_s/data)
- -e:其他参数
- -p:端口映射,将容器内的端口映射到本机端口,前面是本机端口,后面是容器端口。
- -d:镜像名称
步骤4:正常配置主从相关参数
进入容器命令:
[root@lei ~]# docker exec -it pg_p /bin/bash bash-5.0# su - postgres bff818d570c9:~$ psql psql (12.4) Type "help" for help. postgres=#
主库
1.创建复制用户
CREATE ROLE replica login replication encrypted password 'replica'; postgres=# \du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} replica | Replication | {}
2.修改 pg_hba.conf
修改pg_hba.conf
,允许 replica
用户从 172.18.12.101
从库上连接主库。
配置文件在本地:/home/pg_p/data
目录下,如:
host replication replica 172.18.12.101/32 trust #允许172.18.12.101使用 replica 用户来复制
我这里改为0.0.0.0/0
,表示所有IP都可以连接主库,生产环境不要这么设置。
3.修改postgresql.conf
必须修改的配置是前面三个,后面几个看情况修改。
listen_addresses = '*' # 监听所有IP archive_mode = on # 允许归档 wal_level = replica # 开启热备 archive_command = '/bin/date' # 用该命令来归档logfile segment,这里取消归档。 max_wal_senders = 32 # 这个设置了可以最多有几个流复制连接,差不多有几个从,就设置几个 wal_keep_segments = 64 # 设置流复制保留的最多的xlog数目,一份是 16M,注意机器磁盘 16M*64 = 1G wal_sender_timeout = 60s # 设置流复制主机发送数据的超时时间 max_connections = 200 # 这个设置要注意下,从库的max_connections必须要大于主库的
4.最后重启容器,使配置生效。
docker restart pg_p
5.验证配置是否生效
postgres=# show archive_mode; archive_mode-------------- on(1 row)
从库
修改从库相关配置,以及从主库初始化数据过来。
1.初始化数据
进入容器删除原始数据文件,利用pg_basebackup
从主库初始化数据。
[root@lei ~]# docker exec -it pg_s /bin/bash bash-5.0# su - postgres # 删除原有数据文件 cedd81ee4e30:~$ rm -rf /var/lib/postgresql/data/* # 备份恢复 cedd81ee4e30:~$ pg_basebackup -h 172.18.12.100 -p 5432 -U replica -Fp -Xs -Pv -R -D /var/lib/postgresql/data pg_basebackup: initiating base backup, waiting for checkpoint to complete pg_basebackup: checkpoint completed pg_basebackup: write-ahead log start point: 0/2000028 on timeline 1 pg_basebackup: starting background WAL receiver pg_basebackup: created temporary replication slot "pg_basebackup_43" 24636/24636 kB (100%), 1/1 tablespace pg_basebackup: write-ahead log end point: 0/2000138 pg_basebackup: waiting for background process to finish streaming ... pg_basebackup: syncing data to disk ... pg_basebackup: base backup completed
2.新增并配置standby.signal
文件
standby_mode = 'on'
3.修改 postgresql.conf
wal_level = replica # WAL 日志级别为 replica primary_conninfo = 'host=172.18.12.100 port=5432 user=replica password=replica' # 主库连接信息 hot_standby = on # 恢复期间,允许查询 recovery_target_timeline = latest # 默认 max_connections = 120 # 大于等于主节点,正式环境应当重新考虑此值的大小
4.重启容器
[root@lei ~]# docker restart pg_s
步骤5:验证主从是否正常
**方法1:**主库上执行以下命令,可以看到从库信息
postgres=# select client_addr,sync_state from pg_stat_replication; client_addr | sync_state ---------------+------------ 172.18.12.101 | async (1 row)
**方法2:**主库上新建数据库
- 主库
CREATE DATABASE postgres=# postgres=# \c lei You are now connected to database "lei" as user "postgres". lei=# create table test(name varchar(50)); CREATE TABLE lei=# insert into test values('tom'); INSERT 0 1
- 从库
postgres-# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- lei | postgres | UTF8 | en_US.utf8 | en_US.utf8 | postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows) postgres-# \c lei You are now connected to database "lei" as user "postgres". lei=# select * from test; name ------ tom (1 row)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。