Docker 配置 PostgreSQL13 的主从环境

前言

PostgreSQL 数据库支持多种复制解决方案,以构建高可用性,可伸缩,容错的应用程序,其中之一是预写日志(WAL)传送。该解决方案允许使用基于文件的日志传送或流复制,或者在可能的情况下,将两种方法结合使用来实现备用服务器。

默认情况下,流复制是异步的,其中在将事务提交到主服务器后将数据写入备用服务器。这意味着在主服务器中提交事务与更改在备用服务器中变得可见之间存在很小的延迟。这种方法的一个缺点是,如果主服务器崩溃,则可能无法复制任何未提交的事务,这可能导致数据丢失。

本次实验将要在 Docker 上安装 PostgreSQL13 并配置主从环境。为了简化演示环境,这里只用一台服务器来演示,通过不同端口来区分。

安装配置

1. 创建测试网络

创建一个 docker bridge 网络用于测试:

# 1. 创建测试网络
docker network create --subnet=172.18.0.0/24 dockernetwork# 2. 查看网络
docker network lsNETWORK ID     NAME            DRIVER    SCOPE
8c8a87e2c6e0   bridge          bridge    local
a8e4916d92c2   dockernetwork   bridge    local
92951335914e   host            host      local
2e991e7fd5a3   none            null      local

规划主从库IP端口如下:

主库172.18.0.101:5432

从库172.18.0.102:5433

2. 拉取 postgres13 镜像

docker pull postgres

3. 创建数据目录

mkdir -p /data/psql/master
mkdir -p /data/psql/slave
mkdir -p /data/psql/repl
chown 999:999 /data/psql/master
chown 999:999 /data/psql/slave
chown 999:999 /data/psql/repl

4. 运行 master 容器

docker run -d \
--network dockernetwork --ip 172.18.0.101 -p 5432:5432 \
--name master -h master \
-e "POSTGRES_DB=postgres" \
-e "POSTGRES_USER=postgres" \
-e "POSTGRES_PASSWORD=postgres" \
-v /data/psql/master:/var/lib/postgresql/data \
postgres

查看容器:

docker ps -a -f network=dockernetwork --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"NAMES     IMAGE      CREATED          STATUS          NETWORKS        PORTS
master    postgres   48 seconds ago   Up 46 seconds   dockernetwork   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp

5. 创建主从流复制专用账号

# 1. 进入容器
docker exec -it master bash# 2. 连接PostgreSQL
psql -U postgres# 3. 创建用户规则
CREATE ROLE repuser WITH LOGIN REPLICATION CONNECTION LIMIT 5 PASSWORD '123456';
# 用户名 repuser;最大链接数:5;密码:123456# 4. 查看规则
\du
                                   List of rolesRole name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}repuser   | Replication                                               +| {}| 5 connections                                              |

6. 修改 master 配置文件

# 1. 进入 master 文件夹
cd /data/psql/master# 2. 在末尾增加规则
echo "host replication repuser 172.18.0.102/24 md5" >> pg_hba.conf

修改 postgresql.conf 配置文件,找到以下几行,取消注释修改配置:

archive_mode = on               # 开启归档模式
archive_command = '/bin/date'    # 设置归档行为
# 从机连接到主机的并发连接数之总和
max_wal_senders = 10
# 指定在后备服务器需要为流复制获取日志段文件的情况下, pg_wal目录下所能保留的过去日志文件段的最小尺寸
wal_keep_size = 16
# 指定一个支持同步复制的后备服务器的列表
synchronous_standby_names = '*'

更多参数详解可参考:19.6. 复制 (postgres.cn)

7. 重启 master 容器

#使用 pg_ctl stop 安全停止数据库
docker exec -it -u postgres master pg_ctl stop
docker start master

8. 创建 slave 容器

docker run -d \
--network dockernetwork --ip 172.18.0.102 -p 5433:5432 \
--name slave -h slave \
-e "POSTGRES_DB=postgres" \
-e "POSTGRES_USER=postgres" \
-e "POSTGRES_PASSWORD=postgres" \
-v /data/psql/slave:/var/lib/postgresql/data \
-v /data/psql/repl:/var/lib/postgresql/repl \
postgres
# 查看容器
docker ps -a -f network=dockernetwork --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"NAMES     IMAGE      CREATED          STATUS          NETWORKS        PORTS
slave     postgres   18 seconds ago   Up 15 seconds   dockernetwork   0.0.0.0:5433->5432/tcp, :::5433->5432/tcp
master    postgres   2 hours ago      Up 2 hours      dockernetwork   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp

9. 同步数据

# 1. 进入容器
docker exec -it -u postgres slave /bin/bash# 2. 备份主机数据到 repl 文件夹,此处输入在上面设置的密码:123456
pg_basebackup -R -D /var/lib/postgresql/repl -Fp -Xs -v -P -h 172.18.0.101 -p 5432 -U repuserpg_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_154"
24264/24264 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: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed# 3. 备份完成退出容器
exit

10. 重建 slave 容器

通过上一步的初始备份,现在可以使用 /data/psql/repl 里的数据重建 slave容器了。首先删除slave目录,然后将 repl 目录改为 slave,这个目录就是从库的数据目录了:

# 1. 删除容器
docker rm -f slave
# 2. 删除原有文件夹,将 repl 重命名为 slave
cd /data/psql/
rm -rf slave
mv repl slave
cd /data/psql/slave
# 3. 查看配置信息
# postgresql.auto.conf 将含有复制所需信息
cat postgresql.auto.confprimary_conninfo = 'user=repuser password=123456 channel_binding=prefer host=172.18.0.101 port=5432 sslmode=prefer sslcompression=0 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'

重建 slave 容器:

docker run -d \
--network dockernetwork --ip 172.18.0.102 -p 5433:5432 \
--name slave -h slave \
-e "POSTGRES_DB=postgres" \
-e "POSTGRES_USER=postgres" \
-e "POSTGRES_PASSWORD=postgres" \
-v /data/psql/slave:/var/lib/postgresql/data \
postgres
# 查看容器
docker ps -a -f network=dockernetwork --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"NAMES     IMAGE      CREATED          STATUS          NETWORKS        PORTS
slave     postgres   23 seconds ago   Up 21 seconds   dockernetwork   0.0.0.0:5433->5432/tcp, :::5433->5432/tcp
master    postgres   2 hours ago      Up 2 hours      dockernetwork   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp

11. 查看主从复制信息

ps -aux | grep postgres主库进程:
postgres: walsender repuser 172.18.0.1(52678) streaming 0/3000148
从库进程:
postgres: walreceiver streaming 0/3000148

验证主从配置

主机生成数据

# 进入 master 容器,切换到postgres用户
docker exec -it master bash
psql -U postgres
-- 查询复制信息
select * from pg_stat_replication;pid | usesysid | usename | application_name | client_addr | client_hostname...
170 16384   repuser walreceiver 172.18.0.1      52678   2021-09-29 05:57:30.471391+00...
-- 创建测试数据库
CREATE DATABASE test;
-- 查看所有数据库
\listList of databasesName    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +|          |          |            |            | postgres=CTc/postgrestemplate1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +|          |          |            |            | postgres=CTc/postgrestest      | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
(4 rows)
-- 切换数据库
\c test
-- 创建测试表
CREATE TABLE test ("id" int4 NOT NULL,"value" varchar(255),PRIMARY KEY ("id")
);
-- 查看创建的表
\dtList of relationsSchema | Name | Type  |  Owner
--------+------+-------+----------public | test | table | postgres
(1 row)
-- 向表中插入十条数据
insert into test select generate_series(1,10),md5(random());-- 查看所有数据
select * from test;id |              value
----+----------------------------------1 | cfcd208495d565ef66e7dff9f98764da2 | cfcd208495d565ef66e7dff9f98764da3 | cfcd208495d565ef66e7dff9f98764da4 | cfcd208495d565ef66e7dff9f98764da5 | cfcd208495d565ef66e7dff9f98764da6 | cfcd208495d565ef66e7dff9f98764da7 | cfcd208495d565ef66e7dff9f98764da8 | cfcd208495d565ef66e7dff9f98764da9 | cfcd208495d565ef66e7dff9f98764da10 | cfcd208495d565ef66e7dff9f98764da
(10 rows)

从机查看数据

# 进入从机容器
docker exec -it slave bash
psql -U postgres
-- 查看数据库
\dList of databasesName    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +|          |          |            |            | postgres=CTc/postgrestemplate1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +|          |          |            |            | postgres=CTc/postgrestest      | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
(4 rows)
-- 查看表
\c testList of relationsSchema | Name | Type  |  Owner
--------+------+-------+----------public | test | table | postgres
(1 row)
-- 查看所有数据
select * from test;id |              value
----+----------------------------------1 | cfcd208495d565ef66e7dff9f98764da2 | cfcd208495d565ef66e7dff9f98764da3 | cfcd208495d565ef66e7dff9f98764da4 | cfcd208495d565ef66e7dff9f98764da5 | cfcd208495d565ef66e7dff9f98764da6 | cfcd208495d565ef66e7dff9f98764da7 | cfcd208495d565ef66e7dff9f98764da8 | cfcd208495d565ef66e7dff9f98764da9 | cfcd208495d565ef66e7dff9f98764da10 | cfcd208495d565ef66e7dff9f98764da
(10 rows)

可以发现主从数据一直,代表我们主从配置成功!

Docker 配置 PostgreSQL13 的主从环境相关推荐

  1. 如何使用docker配置深度学习开发环境

    文章目录 1.底层驱动的安装 1.1 操作系统的安装 1.2 显卡驱动的安装 1.3 cuda的安装 2.使用docker配置深度学习开发环境 2.1 docker的安装 2.2 nvidia_doc ...

  2. 使用Docker配置cloud9在线开发环境

    前言 关于Docker Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.它是在 LXC 的基础上进行的进一步封装,让用户不需要去关心容器的管理,使得操作更 ...

  3. 使用 Docker 搭建 PostgreSQL 12 主从环境

    环境准备:一台安装了Docker的Linux服务器. 为了简化演示环境,这里只用一台服务器来演示,通过不同端口来区分. 01 - 创建一个docker bridge 网路用于测试 docker net ...

  4. Docker配置mysql互为主从

    配置准备 两台机器 两台机器:A(193.168.10.101)  B(193.168.10.102) 做好ssh免密登录 mysql大版本需要一致,小版本可忽略 并且两台机器已经安装好了docker ...

  5. 【dMRI】desktop docker配置FSL工具链环境

    1.自动下载并启动 docker run --rm -it -v "D:/USC/LONI-student-worker/FSL_workshop":/usr/src/app di ...

  6. 阿里云 docker php mysql_PHP开发环境02 - 阿里云Ubuntu使用Docker配置PHP环境(只限于学习)...

    视频地址 学徒卡夫 - 卡夫的Mac 04 - 阿里云Ubuntu使用Docker配置PHP环境 https://www.bilibili.com/vide... 打包镜像 上传阿里云docker镜像 ...

  7. docker linux 快速开窗口_技术|如何使用 Docker 快速配置数据科学开发环境?

    数据科学开发环境配置起来让人头疼,会碰到包版本不一致.错误信息不熟悉和编译时间漫长等问题.这很容易让人垂头丧气,也使得迈入数据科学的这第一步十分艰难.而且这也是一个完全不常见的准入门槛. 还好,过去几 ...

  8. Docker下redis的主从配置

    Docker下redis的主从配置 1.拉取redis镜像 [tcy@tcy1 ~]$ docker pull daocloud.io/library/redis:latest 2.启动3个redis ...

  9. docker配置深度学习环境

    版权声明:本文为博主原创文章,转载注明出处即可. https://blog.csdn.net/bskfnvjtlyzmv867/article/details/81017226 序 阅读本篇文章可以帮 ...

最新文章

  1. 使用VC++绘制坐标系
  2. 《《python基础》》
  3. 结构体:求最高分和最低分
  4. GDCM:模板空白图片的测试程序
  5. Atomic Integer 原理分析-get方法
  6. 二 SVN代码冲突的解决
  7. Python中的split()和rsplit()的使用
  8. asp.net C#绘制太极图
  9. Java编写的日历,输入年月,输出这个月的日期与星期
  10. 解决Secure Shell Client(SSH)客户端中文乱码的方法
  11. 【狂神说Redis】1NoSQL概述1-2什么是NoSQL
  12. 强悍修改WIN7的文件夹背景(修改DLL)
  13. 互联网专用计算机屏保,18个Windows 98屏保,简直怀念!
  14. pandas安装了但是import不了
  15. 一块蛋清皂,把毛孔洗得一干二净
  16. P3369普通平衡树
  17. java的的socket_java中的socket是什么意思?
  18. 使用宏定义求圆的周长,面积
  19. 灰度共生矩阵(GLCM)计算速度快很多,用numpy写的
  20. 解决微信扫码下载的两个方法

热门文章

  1. 光敏电阻遇上日夜切换
  2. 【含泪提速!】一文全解相似度算法、跟踪算法在各个AI场景的应用(附代码)
  3. C++搭配Easyx绘制小房子
  4. kafka磁盘写满处理
  5. 支付宝支付——当面付
  6. 2019年CSP-J2第三题:纪念品(souvenir)题解
  7. HDU-1009-肥鼠交易 Java
  8. 自驾瑶里 寻觅茶画瓷乡
  9. 1598元配备满血配置,最近买千元手机一定得了解魅族X8
  10. linux平台xpt2046驱动,stm32 触摸屏 XPT2046