使用 Docker 搭建 Postgresql 主备集群

admin 2022年9月28日20:50:01评论951 views字数 4167阅读13分53秒阅读模式
使用 Docker 搭建 Postgresql 主备集群
本文意义
使用 Docker 搭建 Postgresql 主备集群
  • Postgresql 集群,小可热备,中可读写分离,大可作为分布式存储的基础设施;

  • 使用 Docker 搭建,可以隔离开发、测试、生产环境的差异,实现搭建脚本本身的可测试,进一步实现 DevOps 的目标。

为什么不进一步使用 Docker Swarm 或 K8S 等容器编排系统?Postgresl 集群是强状态的,容器编排适合无状态的服务,任由 K8S 进行自动故障迁移会引起 Postgesql 底层数据的更多故障,即使关闭 K8S 的状态迁移,还会因为 PG 服务器之间需要强状态通信,带来很多不必要的编排配置,比脱裤子放屁还多此一举。


使用 Docker 搭建 Postgresql 主备集群
前置条件
使用 Docker 搭建 Postgresql 主备集群
  • Docker: 20+

  • Postgresql: 13 + 镜像


使用 Docker 搭建 Postgresql 主备集群
环境搭建
使用 Docker 搭建 Postgresql 主备集群
Step1 创建虚拟网络

为了不与其它网络环境混淆,我们可以先创建一个 Docker 虚拟网络

docker network create pg-cluster-network

本文演示的是在一台机器上搭建 PG 集群,生产环境的 PG 会搭建在两台机器上,可以忽略此步。

Step2 搭建主数据库

1.创建主库镜像

## 使用postgres官方镜像创建主库容器docker run -d   --restart=unless-stopped   --name=pg-cluster-pg1   --network-alias=pg1   --network pg-cluster-network   -e POSTGRES_DB=test   -e POSTGRES_USER=test   -e POSTGRES_PASSWORD=123456   postgres:13-alpine
  1. 对备库开放远程同步权限

 # 增加备库远程同步权限配置 docker exec -it pg-cluster-pg1   sh -c "echo host replication test all md5 >> /var/lib/postgresql/data/pg_hba.conf"
  1. 开启同步备份 (可选)

同步备份对主库性能影响较大,仅当对备份的事务一致性要求有绝对保障时开放 关闭后,当主库崩溃时,有极小的可能性部分事务未同步 {.is-warning}

 # 开启同步备份 docker exec -it pg-cluster-pg1   sh -c "echo synchronous_standby_names = '*' >> /var/lib/postgresql/data/postgresql.conf"
  1. 重新加载配置

 # 重载配置文件,以便生效 docker exec -it -u postgres pg-cluster-pg1 sh -c "pg_ctl reload"
  1. 创建备份插槽

# 创建备份槽,以便备用服务器接入 docker exec -it pg-cluster-pg1   psql -U test -c "select * from pg_create_physical_replication_slot('standby1_slot');"
Step3 搭建备份数据库

1.创建数据卷,以便从主库同步数据、修改配置

docker volume rm pg-cluster-pg2-data docker volume create pg-cluster-pg2-data
  1. 从主库创建基础备份

# 使用pg_basebackup创建数据库基础备份到数据卷,-R参数会自动生成热备配置到postgresql.auto.conf中 docker run -it --rm   --network pg-cluster-network   -v pg-cluster-pg2-data:/var/lib/postgresql/data   postgres:13-alpine   pg_basebackup -R -h pg1 -U test -X stream -P -S standby1_slot -D /var/lib/postgresql/data

执行时会提示输入主库备份账号密码,输入完成后,会显示备份进度直到 100% 否则失败,则需要检查主库权限配置、网络连接

  1. 启动备份库

 docker run -d   --restart=unless-stopped   --name=pg-cluster-pg2   --network-alias=pg2   --network pg-cluster-network   -v pg-cluster-pg2-data:/var/lib/postgresql/data   postgres:13-alpine
  1. 验证同步状态 在主库中可查询插入状态,来验证备库是否已连接

docker exec -it pg-cluster-pg1  psql -U test -c "SELECT slot_name, slot_type, active, wal_status from pg_replication_slots;"# slot_name     slot_type active  wal_status# standby1_slot physical  t       reserved


使用 Docker 搭建 Postgresql 主备集群
测试数据同步
使用 Docker 搭建 Postgresql 主备集群
  1. 搭建 pgadmin 用于测试

 docker run -d   --restart=unless-stopped   --name=pg-cluster-pgadmin   --network pg-cluster-network   -p 8888:80   -e PGADMIN_DEFAULT_EMAIL=admin   -e PGADMIN_DEFAULT_PASSWORD=123456   dpage/pgadmin4:snapshot

pgadmin 容器创建后,可以在 http://localhost:8888 上配置到 pg1、pg2 的连接 因为设置了网络别名,两台数据库服务器可以用 pg1、pg2 代替 ip 直接访问 pgadmin 的账号 / 密码为:admin/123456

  1. 在主库中创建测试表并插入数据 在 pg1.test 库中执行以下 sql

CREATE TABLE userInfo(    userName VARCHAR(20),    age INT,    PRIMARY KEY(userName));INSERT INTO userInfo VALUES('张三',10);

在 pg2.test 中执行以下查询

SELECT * FROM userInfo;

如果看到刚在 pg1.test 中插入的数据,则说明主备已经搭建成功


使用 Docker 搭建 Postgresql 主备集群
故障恢复
使用 Docker 搭建 Postgresql 主备集群

当主库崩溃时,需要进行故障转移或恢复

请谨慎执行以下操作,否则有可能会造成主备数据不同步 {.is-warning}

故障处理方案一:转移到备库

备库默认是只读的,可以用来分担只读负载,可以通过以下 sql 来验证,正常情况会报数据库只读

-- 在 pg2.test中执行UPDATE userInfo SET age=4;-- ERROR:  cannot execute UPDATE in a read-only transaction-- SQL 状态: 25006

当主库挂掉时,可快速在备库中执行命令将备库转换为主库:方式一:使用 SQL

-- 在pg2.test中执行:SELECT pg_promote(true,60);-- 参数1:等待提升完成-- 参数2:等待60秒

方式二:使用 pg_ctl 命令

docker exec -it -u postgres pg-cluster-pg2  pg_ctl promote

将备库转换为主库后,需另外再搭建备份库来保证下次的故障转移

故障处理方案二:主库恢复

步骤一 主库反向从备库恢复数据 (可选)

大部分情况下,如主机断电等,只需要将主库启动并连接到网络即可完成恢复 当且仅当主库文件系统损坏等情况造成数据丢失时,需要从备库恢复数据

1. 备库中向主库开放插槽
 # 在原备库中创建备份槽,以便原主库接入并恢复数据 docker exec -it pg-cluster-pg2   psql -U test -c "select * from pg_create_physical_replication_slot('main_slot');"
2 从备份库恢复数据
 # 创建docker数据卷 docker volume rm pg-cluster-pg1-data docker volume create pg-cluster-pg1-data # 使用pg_basebackup从备份库恢复数据到数据卷,-R参数会自动生成热备配置到postgresql.auto.conf中 docker run -it --rm   --network pg-cluster-network   -v pg-cluster-pg1-data:/var/lib/postgresql/data   postgres:13-alpine   pg_basebackup -R -h pg2 -U test -X stream -P -S main_slot -D /var/lib/postgresql/data
3. 配置主库在数据同步完成后自动升级为主库

如果备库已经升级为主库,不要执行本操作!否则有可能造成主备数据不一致!{.is-warning}

在主库启动后,可手动执行 pg_promote 进行升级,也无须执行本节操作 如果数据较大、恢复时间较长,考虑使用以下方式

 # 配置升级触发文件 docker run -it --rm   --network pg-cluster-network   -v pg-cluster-pg1-data:/var/lib/postgresql/data   postgres:13-alpine   sh -c "echo promote_trigger_file = 'standby.signal' >> /var/lib/postgresql/data/postgresql.conf"

当主库启动成功恢复后,其会自动切换到主库状态,提供正常的读写服务

步骤二 启动主库

 docker run -d   --restart=unless-stopped   --name=pg-cluster-pg1   --network-alias=pg1   --network pg-cluster-network   -v pg-cluster-pg1-data:/var/lib/postgresql/data   postgres:13-alpine

等主库启动完毕,验证下数据没有丢失,即已完成主库的恢复,如果发现数据丢失,请执行步骤一

作者:chentao106

来源:OSC DevOps 社区

链接:https://my.oschina.net/u/4254626/blog/5403511

使用 Docker 搭建 Postgresql 主备集群

使用 Docker 搭建 Postgresql 主备集群
使用 Docker 搭建 Postgresql 主备集群
助力DevOps文化传播与实践


原文始发于微信公众号(OSC DevOps):使用 Docker 搭建 Postgresql 主备集群

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年9月28日20:50:01
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   使用 Docker 搭建 Postgresql 主备集群http://cn-sec.com/archives/1322009.html

发表评论

匿名网友 填写信息