使用 Docker 搭建 PostgreSQL 12 主从环境

环境准备:一台安装了Docker的Linux服务器。

为了简化演示环境,这里只用一台服务器来演示,通过不同端口来区分。

01


创建一个docker bridge 网路用于测试

docker network create --subnet=172.18.0.0/24 dockernetwork
docker network ls

设置了网段为 172.18.0.0,规划主从库IP端口如下:

主库 172.18.0.101:5432

从库 172.18.0.102:5433

02


拉取 postgres:12 镜像

docker pull postgres:12

03


创建数据库数据目录

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

master:主库数据

slave:从库数据

repl:临时使用复制数据

04


运行master容器

docker run -d \
--network dockernetwork --ip 172.18.0.101 -p 5432:5432 \
--name pg12master -h pg12master \
-e LANG="C.UTF-8" \
-e 'TZ=Asia/Shanghai' \
-e "POSTGRES_DB=postgres" \
-e "POSTGRES_USER=postgres" \
-e "POSTGRES_PASSWORD=postgres" \
-v /data/psql/master:/var/lib/postgresql/data \
postgres:12

05


查看容器运行情况

docker ps -a -f network=dockernetwork --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"

06


创建主从流复制专用账号

用客户端工具连接数据库后执行以下语句,这里我使用了pgAdmin4。

CREATE ROLE repuser WITHLOGINREPLICATIONCONNECTION LIMIT 5PASSWORD 'Q1w2E#';

pgAdmin 也可以用 docker 来启动。

docker pull dpage/pgadmin4
mkdir -p /data/pgadmin4
chown 5050:5050 /data/pgadmin4docker run -d --restart=unless-stopped \
--network dockernetwork --ip 172.18.0.105 \
--name pgadmin4 -h pgadmin4 \
-e TZ=Asia/Shanghai \
-e 'PGADMIN_DEFAULT_EMAIL=admin@pgadmin4.com' \
-e 'PGADMIN_DEFAULT_PASSWORD=pgadmin4' \
-p 5430:80 \
-v /data/pgadmin4:/var/lib/pgadmin \
dpage/pgadmin4

通过 http://ip:5430/即可访问pgadmin4,账号密码如脚本所示。具体使用也很简单,自己摸索下就懂了。

07


修改配置文件 /data/psql/master/pg_hba.conf

cd /data/psql/master
nano pg_hba.conf

在文末添加如下一行,其中 repuser 即我们新建的主从专用账号,172.18.0.102/32 为从库 ip。

host replication repuser 172.18.0.102/32 md5

08


修改配置文件 /data/psql/master/postgresql.conf

nano postgresql.conf

查找文件中以下几个参数,并调整如下:

archive_mode = on
archive_command = '/bin/date'
max_wal_senders = 10
wal_keep_segments = 16
synchronous_standby_names = '*'

09


重启主库使设置生效

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

10


创建从库容器

docker run -d \
--network dockernetwork --ip 172.18.0.102 -p 5433:5432 \
--name pg12slave -h pg12slave \
-e LANG="C.UTF-8" \
-e 'TZ=Asia/Shanghai' \
-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:12

这里我们把/data/psql/repl挂载到容器中,再看下容器列表:

docker ps -a -f network=dockernetwork --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"

主从库容器都已经跑起来了,当然了,这个从库还没配置。

11


进入从库容器,同步初始主库数据到 repl 目录

docker exec -it -u postgres pg12slave /bin/bash
pg_basebackup -R -D /var/lib/postgresql/repl -Fp -Xs -v -P -h 172.18.0.101 -p 5432 -U repuser

根据提示输入repuser的密码Q1w2E#后,会在宿主机的 /data/psql/repl 目录生成备份。

备份成功,退出容器。

exit

12


重建 slave 容器

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

docker stop pg12slave && docker rm pg12slave
cd /data/psql/
rm -rf slave
mv repl slave
cd /data/psql/slave# postgresql.auto.conf 将含有复制所需信息
cat postgresql.auto.conf

检查 postgresql.auto.conf 文件里是否包含如下内容:

primary_conninfo = 'user=repuser password=''Q1w2E#'' host=172.18.0.101 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'

正确无误后,重建容器。

# 恢复重建从库容器
docker run -d \
--network dockernetwork --ip 172.18.0.102 -p 5433:5432 \
--name pg12slave -h pg12slave \
-e LANG="C.UTF-8" \
-e 'TZ=Asia/Shanghai' \
-e "POSTGRES_DB=postgres" \
-e "POSTGRES_USER=postgres" \
-e "POSTGRES_PASSWORD=postgres" \
-v /data/psql/slave:/var/lib/postgresql/data \
postgres:12

这里不再挂载repl了,slave容器运行起来后,主从创建完成。

13


查看主从复制信息

# 验证主从
ps -aux | grep postgres
# 主库有 walsender 进程如下
postgres: walsender repuser
# 从库有 walreceiver 进程如下
postgres: walreceiver

连接主库,通过sql可以查询复制信息:

select * from pg_stat_replication;

14


总结

以上是在单机环境下的演示,在实际生产环境中,只要调整相应的账号密码ip端口即可实现类似效果,其他配置信息具体根据自己需要再行调整。

dotnet core 下连接PostgreSQL的库主要是Npgsql,Entity Framework Core 下可以使用包Npgsql.EntityFrameworkCore.PostgreSQL。相较于MySQL,PostgreSQL对SQL标准的支持更完整,功能更强大。网上对这两个数据库的比较很多,这里就不多赘述了。

欢迎关注公众号 "dotnet 新征程"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab gui 密码登录 论文,MATLAB GUI 密码输入

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼function varargout zhanghao(varargin)% ZHANGHAO MATLAB code for zhanghao.fig% ZHANGHAO, by itself, creates a new ZHANGHAO or raises the existing% singleton*.%% H ZHANGHAO returns the handle to a new ZHANGHAO or …

Paint the Tree CodeForces - 1244D(看似是树,其实是条链)

目录题目官方题解:百度翻译题解ac代码题目 给多组两顶点连接,得到的图任意三个顶点都是不同的颜色,,给出各顶点染三种颜色的花费,问各店如何染,满足条件情况下,使得花费最少; You …

[设计模式]简单工厂模式

简单工厂模式优点: 1.客户端和具体实现解耦 2.对于某些对象的创建过程比较复杂的情况,我们不用考虑这些。 简单工厂模式缺点: 1.简单工厂模式,增加新的功能是通过修改源代码实现,不符合开闭原则。 2.这个工厂(类)职责过重,这个…

什么前浪后浪,我们只不过是时代大潮中的一朵小浪花

这是头哥侃码的第198篇原创上周的五四青年节,我的朋友圈被一个短视频刷屏了,不知道你的朋友圈有没有被刷到?这个短视频来自小破站B站的一则宣传视频《后浪》。我是B站的老用户,所以在看完视频后,我特地跑到B站看了下&a…

java上GUI表格按钮,java GUI表格实例

1 package javademo;2 import java.awt.*;3 import javax.swing.*;4 import java.awt.event.*;5 public class table3{6 JFrame framenew JFrame("表格实例");7 Object [][]date {{"李明",45,"计算机"},{8 "小王",32,"数学"…

[设计模式]工厂方法模式

工厂方法模式缺点: 1.类的个数成倍增加,导致类越来越多,增加维护成本。 2.增加了系统的抽象性和理解难度。 (判断生产什么,又变成让客户端来判断了,简单工厂模式是由工厂判断) 工厂方法模式优点: 1.符合开闭原则。 简单工厂模式…

Asp.Net Boilerplate微服务实战(二)架构解析

这一章节,我来介绍一下Asp.Net Boilerplate框架在微服务开发中所用到的技术及其大体的组织架构。由于本系列仅讨论ABP框架在微服务架构下的应用方案,不涉及具体的业务逻辑,所以在文中,不讨论服务拆分方案等细节,也未采…

Power Strings POJ - 2406(求一串字符串中有多少个循环节)

题意: 有一串字符串,问求出有多少个循环节连续重复组成,即可以用KMP直接求出循环节有多少个字符组成。答案就是l/next[l](刚开始理解错题意,认为是找出最多的重复子串) 题目 Given two strings a and b we define a…

redis lua 抽奖 PHP,通过redis+lua实现加减库存

一. 场景下单后库存校验或者秒杀场景下,有很多利用“锁”的方案来解决问题。但是加锁其实是一件性价比很低的事,所以我们采用用redislua的方式来实现这个功能。二. 思路阶段一:在库存加减逻辑中分为2个步骤:STEP1.读取库存&#x…

[设计模式]简单工厂和工厂方法模式适用场景

简单工厂模式 适用场景: 1.工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。 2.客户端只知道传入工厂类的参数,对于如何创建对象并不关心。 工厂方法模式 适用场景: 1.客户端不知道它所需要的对象…

Too Many Segments (easy version) CodeForces - 1249D1(贪心+差分)

题意 给多组线段,而每一个点的覆盖次数不超过K,每次可去除一个线段,问最少去多少线段以及线段的位置。 The only difference between easy and hard versions is constraints. You are given nn segments on the coordinate axis OX. Segme…

c#: 协变和逆变深度解析

环境&#xff1a;window 10.netcore 3.1vs2019 16.5.1一、为什么要有协变&#xff1f;首先看下面的代码&#xff1a;还有下面的&#xff1a;其实上面报错的是同一个问题&#xff0c;就是你无法用List<Fruit>指向List<Apple>&#xff01;我们的疑问在于&#xff0c;…

[设计模式]抽象工厂模式

抽象工厂模式针对的是产品族&#xff0c;而不是产品等级结构。 产品族:同一产地或者同一产商&#xff0c;功能不同。 产品等级:功能相同&#xff0c;产地或者厂商不同。 代码如下: #include <iostream> using namespace std;class AbstractApple { public:virtual vo…

Too Many Segments (hard version) CodeForces - 1249D2(贪心+容器vector+set)

题目 给多组线段&#xff0c;而每一个点的覆盖次数不超过K&#xff0c;每次可去除一个线段&#xff0c;问最少去多少线段以及线段的位置。 The only difference between easy and hard versions is constraints. You are given nn segments on the coordinate axis OX. Segme…

.net core HttpClient 使用之掉坑解析(一)

一、前言在我们开发当中经常需要向特定URL地址发送Http请求操作&#xff0c;在.net core 中对httpClient使用不当会造成灾难性的问题&#xff0c;这篇文章主要来分享.net core中通过IHttpClientFactory 工厂来使用HttpClient的正确打开方式。二、HttpClient使用中的那些坑2.1 错…

linux常用命令 java,Java工程在Linux常用命令

Java Web工程 在Linux下操作常用命令cd ../ 退出当前目录,前往父文件夹cd ezoffice 进入ezoffice文件夹ls 查看目录ps -ef|grep java 查看JAVA进程ps -aux |grep tomcat 查看tomcat进程 的进程号kill -9 12222 杀死ID为12222进程nohup ./startup.sh & 执行startup.sh&…

[设计模式]单例模式(懒汉式,饿汉式)

实现单例步骤: 1.构造函数私有化。 2.增加静态私有的当前类的指针变量。 3.提供静态对外接口&#xff0c;可以让用户获得单例对象。 单例 分为&#xff1a; 1.懒汉式 2.饿汉式 懒汉式 代码如下: class Singleton_lazy { public:static Singleton_lazy *getInstance(){if (pS…

By Elevator or Stairs? CodeForces - 1249E(动态规划)

题意 n层楼&#xff0c;a[i] (0<i<n)表示从 i 楼到 i 1 楼走楼梯的时间&#xff0c;b[i] (0<i<n)表示从 i 楼到 i 1 楼乘电梯的时间&#xff0c;其中每一次乘电梯需要等待 k 时间&#xff0c;楼梯和电梯一次均可上从 x 楼上升到 y 楼 ( y ! x )&#xff0c;即一…

我擦!没想到你们都是这样 “劝退” 员工的!

前几天&#xff0c;我的一个好哥们在微信上跟我吐槽&#xff0c;说这波疫情对经济的影响实在太大了。他说在往年&#xff0c;这个时候跳槽应该开始冒头了&#xff0c;而今年从春节到现在&#xff0c;除了少数几个被裁员之外&#xff0c;200多人的技术团队几乎就没一个主动提离职…

php post nginx 400,Nginx静态文件响应POST请求 提示405错误的解决方法

例1&#xff1a;用linux下的curl命令发送POST请求给Apache服务器上的HTML静态页[rootlocalhost ~]# curl -d 111 https://www.jb51.net/index.html405 Method Not AllowedMethod Not AllowedThe requested method POST is not allowed for the URL /index.html.Apache/1.3.37 S…