Linux下PostgreSQL主备环境搭建和切换

2023-10-27

1. 概念

数据库热备:数据库热备是指为主数据库的创建、维护和监控一个或多个备用数据库,它们时刻处于开机状态,同主机保持同步。当主机失灵时,可以随时启用热备数据库来代替,以保护数据不受故障、灾难、错误和崩溃的影响。

流复制(streaming replication):PostgreSQL提供的一种服务器间的数据复制方式。这种方式下,后备服务器连接到主服务器,主服务器则在 WAL 记录产生时即将它们以流式传送给后备服务器而不必等到 WAL 文件被填充。

2. 实验环境

服务器两台。

操作系统:Linux CentOS 6.6

软件:PostgreSQL 10.0

主服务器的IP地址为10.40.239.101,后备服务器IP 地址为 10.40.239.102。

3. 实验过程

3.1 实验准备

两台虚拟机上都安装了PostgreSQL 10.0,它们的安装目录是:/opt/postgresql10/

在/etc/profile 中添加如下几行:

export PATH=/opt/postgresql10/bin:$PATH

export LD_LIBRARY_PATH=/opt/postgresql10/lib:$LD_LIBRARY_PATH

export PGDATA=/opt/postgresql10/data

 

随后加载使之生效:

source /etc/profile

 

3.2 搭建PostgreSQL 主备环境。

3.2.1 主节点上的操作

1. 确保服务已经启动。执行命令:

 su postgres

切换用户,并执行:

pg_ctl start -D $PGDATA

启动服务。

2. 创建用于流复制的用户。执行命令:

psql -h 127.0.0.1 -p 5432 -U postgres

进入控制台,并执行如下语句创建用户:

create user repuser with login replication password '123456';

 

3. 修改pg_hba.conf 文件,添加如下内容,允许两台计算机上的复制用户和超级用户登录:

host    replication     repuser         10.33.45.101/32         md5

host    replication     repuser         10.33.45.102/32         md5

host      all           postgres           10.33.45.101/32              trust

host      all           postgres           10.33.45.102/32              trust

 

4. 在主节点的 postgresql.conf 中设置这些参数:

max_wal_senders = 10
wal_level = replica
wal_log_hints = on
wal_keep_segments = 10
wal_receiver_status_interval = 5s
hot_standby_feedback = on

这些参数中的含义如下:

max_wal_senders表示来自后备服务器或流式基础备份客户端的并发连接的最大数量;

wal_level 表示日志级别,对于流复制,它的值应设置为replica;

wal_log_hints = on表示,在PostgreSQL服务器一个检查点之后页面被第一次修改期间,把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做;

wal_keep_segments 指定在后备服务器需要为流复制获取日志段文件的情况下,pg_wal(PostgreSQL 9.6 以下版本的是pg_xlog)目录下所能保留的过去日志文件段的最小数目。

log_connections 表示是否在日志中记录客户端对服务器的连接;

wal_receiver_status_interval 指定在后备机上的 WAL 接收者进程向主服务器或上游后备机发送有关复制进度的信息的最小周期;

hot_standby_feedback 指定一个热后备机是否将会向主服务器或上游后备机发送有关于后备机上当前正被执行的查询的反馈,这里设置为on。

关于详细内容,可以参考postgresql官方文档。

 

5. 重启主节点:

pg_ctl restart -D $PGDATA

 

6. 重启之后,为主服务器和后备服务器创建复制槽,这一步不是必须的。

select * from pg_create_physical_replication_slot('postgresql_node101');

select * from pg_create_physical_replication_slot(' postgresql_node102');

 

复制槽(replication slot)的作用是:

1. 在流复制中,当一个备节点断开连接是时,备节点通过hot_standby_feedback 提供反馈数据数据会丢失。当备节点重新连接时,它可能因为被主节点发送清理记录而引发查询冲突。复制槽即使在备节点断开时仍然会记录下备节点的xmin(复制槽要需要数据库保留的最旧事务ID)值,从而确保不会有清理冲突。

 

2. 当一个备节点断开连接时,备节点需要的WAL文件信息也丢失了。如果没有复制槽,当备节点重连时,我们可能已经丢弃了所需要的WAL文件,因此需要完全重建备节点。而复制槽确保这个节点保留所有下游节点需要的wal文件。

 

3.2.2 备节点上的操作

1. 确保服务是停止的:

su postgres

切换用户,并执行:

pg_ctl stop -D $PGDATA

关闭服务。

2. 首先删除备节点中的数据目录 $PGDATA 中的文件:

cd $PGDATA

rm –rf *

然后执行:

pg_basebackup -Xs -d "hostaddr=10.33.45.101 port=5432 user=repuser password=123456" -D $PGDATA -v -Fp 

这里,-Xs 表示复制方式是流式的(stream),这种方式不会复制在此次备份开始前,已经归档完成的WAL文件;-d 后面是一个连接字符串,其中“hostaddr=10.40.239.101”表示主服务器的ip地址是10.40.239.101,“port=5432”表示数据库的端口是5432,“user=repuser”表示用于流复制的用户是repuser, “password=123456”表示密码是123456;“-D $PGDATA”表示将备份内容输入到本地的 $PGDATA 目录;“-v”表示打印详细信息,–Fp 表示复制结果输出位普通(plain)文件。

3. 基础备份完成后,修改备节点的 postgresql.conf 文件,设置:

hot_standby = on

 

4. 将 /opt/postgresql10/share/ 中的 recovery.conf.sample 拷贝到 $PGDATA 下,重命名为 recovery.conf:

cp /opt/postgresql10/share/recovery.conf.sample $PGDATA/recovery.conf

并设置如下参数:

recovery_target_timeline = 'latest'
standby_mode = on
primary_conninfo = 'host=10.40.239.101 port=5432 user=repuser password=repuser123'
primary_slot_name = 'postgresql_node102'
trigger_file = 'tgfile'

这些参数的含义如下:

recovery_target_timeline 表示恢复到数据库时间线的上的什么时间点,这里设置为latest,即最新。

standby_mode 表示是否将PostgreSQL服务器作为一个后备服务器启动,这里设置为on,即后备模式。

primary_conninfo指定后备服务器用来连接主服务器的连接字符串,其中“host=10.40.239.101”表示主服务器的ip地址是10.40.239.101,“port=5432”表示数据库的端口是5432,“user=repuser”表示用于流复制的用户是repuser, “password=123456”表示密码是123456。

primary_slot_name 指定通过流复制连接到主服务器时使用一个现有的复制槽来控制上游节点上的资源移除。这里我们指定3.2.1节创建的postgresql_node102。如果没有在主服务器上创建复制槽,则不配置此参数。

trigger_file指定一个触发器文件,该文件的存在会结束后备机中的恢复,使它成为主机。

 

5. 启动备节点服务:

pg_ctl start -D $PGDATA

 

3.3 主备环境检测

1. 在主节点上创建一个表,并插入数据:

postgres=# create table student  (id int, name text);

CREATE TABLE

postgres=# insert into student  (id, name)  values  (1,'tom');

INSERT 0 1

 

2. 在备节点上检测:

postgres=# select * from student;

 id | name

----+------

  1 | tom

主节点数据同步到了备机。

同时,在备节点上写数据会失败:

postgres=# insert into student (id, name)  values  (2,'amy');

ERROR:  cannot execute INSERT in a read-only transaction

3.4 主备环境的切换

1. 激活备节点,使之成为新的主结点:

pg_ctl promote -D $PGDATA

结果是:

waiting for server to promote........ done

server promoted

 

2. 查看新主节点的状态:

postgres=#  pg_controldata | grep cluster

Database cluster state:               in production

插入一条数据:

postgres=#  insert into student (id, name)  values  (2,'amy');

INSERT 0 1

 

3. 停止旧的主结点:

pg_ctl stop -m fast -D $PGDATA

结果:

waiting for server to shut down.... done

server stopped

 

4. 在停止的旧主结点上执行恢复数据的操作:

pg_rewind --target-pgdata $PGDATA --source-server='host=10.33.45.102 port=5432 user=postgres dbname=postgres' -P

结果如下:

connected to server

servers diverged at WAL location 0/2B000230 on timeline 4

rewinding from last common checkpoint at 0/2A000098 on timeline 4

reading source file list

reading target file list

reading WAL in target

need to copy 57 MB (total source directory size is 143 MB)

58749/58749 kB (100%) copied

creating backup label and updating control file

syncing target data directory

Done!

表示从新主节点上成功获取WAL日志。

5. 重新配置旧主结点的 recovery.conf:

recovery_target_timeline = 'latest'
standby_mode = on
primary_conninfo = 'hostaddr=10.40.239.102 port=5432 user=repuser password=repuser123'
primary_slot_name = 'postgresql_node101'

 

6. 在旧主结点上执行下面的命令,重新启动该节点:

pg_ctl start -D $PGDATA

 

7. 在旧主结点上验证:

postgres=# insert into student (id, name)  values  (3,'lily');

ERROR:  cannot execute INSERT in a read-only transaction

现在,它成为了新的备节点。

这样,我们就实现了linux下的主备节点的切换。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux下PostgreSQL主备环境搭建和切换 的相关文章

  • PostgreSQL 中的逆透视表

    我有下表作为 SUM Case End 的结果 Account Product A Product B Product C 101 1000 2000 3000 102 2000 1000 0 103 2000 1000 0 104 200
  • 对 sf:: 的未定义引用

    我想用 C 制作 GUI 应用程序 发现 SFML 是一个不错的选择 幸运的是 我使用的是 Linux 所以 SFML 2 4 已经安装在我的系统上 所以我开始搜索一些教程并找到了一个制作简单窗口的教程 但是当我运行代码时 出现错误 提示未
  • 使用 MongoDB docker 镜像停止虚拟机而不丢失数据

    我已经在 AWS EC2 上的虚拟机中安装了官方的 MongoDB docker 映像 并且数据库上已经有数据 如果我停止虚拟机 以节省过夜费用 我会丢失数据库中包含的所有数据吗 在这些情况下我怎样才能让它持久 有多种选择可以实现此目的 但
  • 变量作为 bash 数组索引?

    bin bash set x array counter 0 array value 1 array 0 0 0 for number in array do array array counter array value array co
  • Azure PostgreSQL 服务器服务排序规则创建错误

    我正在尝试将当前现有数据库导入到 Azure PostgreSQL 服务器上运行的 postgre 实例 我已经将我的azure postgresql服务器参数配置为使用UTF8编码 我不确定它是否在不重新启动的情况下应用 但即使我没有重新
  • 使用netcat将unix套接字传输到tcp套接字

    我正在尝试使用以下命令将 unix 套接字公开为 tcp 套接字 nc lkv 44444 nc Uv var run docker sock 当我尝试访问时localhost 44444 containers json从浏览器中 它不会加
  • 将enable_nestloop设置为OFF有哪些陷阱

    当我的表中有大量行时 我的应用程序中有一个查询运行得非常快 但是 当行数适中 既不大也不小 时 相同的查询运行速度会慢 15 倍 解释计划显示对中等规模数据集的查询正在使用嵌套循环其连接算法 大数据集使用散列连接 我可以阻止查询规划器在数据
  • 是否有可能通过 mmap 匿名内存“打孔”?

    考虑一个使用大量大致页面大小的内存区域 例如 64 kB 左右 的程序 每个内存区域的寿命都相当短暂 在我的特定情况下 这些是绿色线程的替代堆栈 如何最好地分配这些区域 以便一旦该区域不再使用 它 们的页面可以返回到内核 天真的解决方案显然
  • 使用 pg-promise 进行多行插入

    我想用一个插入多行INSERT查询 例如 INSERT INTO tmp col a col b VALUES a1 b1 a2 b2 有没有一种方法可以轻松地做到这一点 最好是对于像这样的对象数组 col a a1 col b b1 co
  • 如何在 Linux 中使用单行命令获取 Java 版本

    我想通过单个命令获取 Linux 中的 Java 版本 我是 awk 的新手 所以我正在尝试类似的事情 java version awk print 3 但这不会返回版本 我将如何获取1 6 0 21从下面的Java版本输出 java ve
  • 编写多个mysql脚本

    是否可以在复合脚本中包含其他 mysql 脚本 理想情况下 我不想为包含的脚本创建存储过程 对于较大的项目 我想分层维护几个较小的脚本 然后根据需要组合它们 但现在 我很乐意学习如何包含其他脚本 source是一个内置命令 您可以在 MyS
  • 如何使用ffmpeg重叠和合并多个音频文件?

    我正在尝试将多个音频文件合并到一个文件中 但我可以使用以下命令来连接 而不是连接 ffmpeg v debug i file1 wav i file2 wav i file3 wav filter complex 0 0 concat n
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • 如何在一列中存储数组或多个值

    运行 Postgres 7 4 是的 我们正在升级 我需要将 1 到 100 个选定项目存储到数据库的一个字段中 98 的情况下 只会输入 1 个项目 而 2 的情况下 如果是这样的话 会输入多个项目 这些项目只不过是文本描述 截至目前 长
  • Alembic 无法识别 False 默认值

    在维护 SQLAlchemy 数据模型并利用 alembic 进行版本控制时 我所做的以下代码更改导致了空修订 some column Column Boolean nullable False default False 以前是 some
  • linux下如何获取昨天和前天?

    我想在变量中获取 sysdate 1 和 sysdate 2 并回显它 我正在使用下面的查询 它将今天的日期作为输出 bin bash tm date Y d m echo tm 如何获取昨天和前天的日期 这是另一种方法 对于昨天来说 da
  • Gradle 1.3:build.gradle 不构建类

    这里有一个新问题 我有一个 build gradle 文件apply plugin java在其中 并与 java 项目 包关联 当我跑步时gradle build从命令行我得到 compileJava UP TO DATE process
  • 哪种 SQL 模式能够更快地避免插入重复行?

    我知道有两种不重复插入的方法 第一个是使用WHERE NOT EXISTS clause INSERT INTO table name col1 col2 col3 SELECT s s s WHERE NOT EXISTS SELECT
  • 如何从 Linux 的 shell 中删除所有以 ._ 开头的文件?

    确实如标题所示 我已将许多文件从 Mac 复制到 Raspberry Pi 这导致了许多以前缀开头的多余文件 我想删除以以下开头的文件夹中的每个文件 我该怎么做 尝试类似的方法 cd path to directory rm rf 或者 如
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理

随机推荐

  • 机器学习的训练数据(Training Dataset)、测试数据(Testing Dataset)和验证数据(Validation Dataset)

    三者的意义 训练数据 用来训练模型的数据 验证数据 用来检验模型准确率 测试数据 再一次确认验证数据集中的模型是好的模型 一般步骤 测试数据集和验证数据的数据一定不能用来训练 否则会出现过拟合的现象 代码 import math impor
  • linux笔记(10):ubuntu环境下,基于SDL2运行lvgl+ffmpeg播放mp4

    文章目录 1 ubuntu安装ffmpeg 1 1 源码安装 1 1 克隆ffmpeg源码 1 2 配置编译条件 编译 安装 1 2 直接安装依赖包 2 下载lvgl源码 2 1 测试原始代码 2 2 运行lv example ffmpeg
  • Linux查看CPU和内存使用情况

    top命令 top命令是Linux下常用的性能分析工具 能够实时显示系统中各个进程的资源占用状况 类似于Windows的任务管理器 运行 top 命令后 CPU 使用状态会以全屏的方式显示 并且会处在对话的模式 用基于 top 的命令 可以
  • Unity UGUI Content 可以动态改变大小

    在UGUI中Scroll View是常用的一个东西 但是在加载内容的时候 有时候需要动态调整Content的大小 这时候就可以在Content上加上组件ContentSizeFitter这个组件 然后把可以选择的东西选择这个模式就可以了
  • C++中clock()函数的使用

    函数声明 clock t clock void clock t 是 long 型 typedef long clock t clock 使用的头文件是 time h CLOCK PER SEC表示每一秒经历的时钟数 通常我们用clock t
  • 告别枯燥乏味的编程学习,在欢声笑语中学会Python,华为大佬极力推荐Python漫画书!

    Python是学习大数据 人工智能时代的首选编程语言 Python因上手简单被越来越多的人所喜爱 每年使用人数在各类语言中稳居前二 而且每年是用人数还在直线上升 但是对于想要入门Python的同学仍一头雾水 虽然网上的资料很多 但是很多资料
  • 建站系列(七)--- 常用前后端框架

    目录 相关系列文章 前言 一 何为框架 二 为什么使用框架 三 常用框架 一 Bootstrap 二 Layui 三 JQuery 四 Vue js 四 ThinkPHP 五 Spring Boot 相关系列文章 建站系列 一 网站基本常识
  • 大家一起学电脑之硬件版

    大家一起学电脑之硬件版 首先文章还是先从硬件的认识开始 再到安装操作系统的注意事项 再到进入与退出系统可能发生的情况与问题 然后再说单个硬件的详解 最后再说故障和技巧吧 晕 因为有些文章因为发现的晚 所以排序有点儿乱了 0 38 02 11
  • 区块链开发

    区块链开发如今常见的语言有哪一些 区块链技术其实在如今的市场上已经得到大家的关注 这是大部分人可能并不了解 这到底是一种什么样的技术 为什么各大行业的巨头都会比较关注呢 如今的区块链开发已经进入到火热的阶段 那么你是否知道到底包含哪一种主要
  • Mybatis 是如何进行分页的?分页插件的原理是什么?

    1 Mybatis 使用 RowBounds 对象进行分页 也可以直接编写 sql 实现分页 也可以使用 Mybatis 的分页插件 2 分页插件的原理 实现 Mybatis 提供的接口 实现自定义插件 在插件的拦截方法内拦 截待执行的 s
  • git 如何解决 (master

    git 如何解决 master MERGING git reset hard head 回退版本信息 git pull origin master 转载于 https www cnblogs com 651434092qq p 110188
  • 国产开源新标杆!20B大模型,性能媲美Llama2-70B,单卡可推理

    明敏 发自 凹非寺量子位 公众号 QbitAI 国产新标杆 免费可商用的200亿参数大模型 来了 书生 浦语大模型 InternLM 20B版本正式发布 一举刷新国内新一代大模型开源纪录 它由上海人工智能实验室 上海AI实验室 与商汤科技联
  • MySQL入门---超详细安装及基本使用教程

    数据库技术和数据库系统 数据库技术和数据库系统已经成为计算机信息系统的核心技术和重要基础 gt gt MySQL简介 MySQL是一款单进程多线程 支持多用户 基于客户机 服务器 Client Server C S 的关系数据库管理系统 是
  • 怎么使用blender

    Blender是一款开源3D建模和动画软件 可以用来制作三维图像 动画 游戏 音频和视频 要使用Blender 需要先下载并安装该软件 安装完成后 打开Blender 您会看到一个3D空间 包含一个默认的立方体 可以通过鼠标和键盘来对立方体
  • strdup函数的用法

    函数名 strdup 功 能 将串拷贝到新建的位置处 用 法 char strdup char str 这个函数在linux的man手册里解释为 The strdup function returns a pointer toa new s
  • 推荐系统实战5——EasyRec 在DSSM召回模型中添加负采样构建CTR点击平台

    推荐系统实战5 EasyRec 在DSSM召回模型中添加负采样构建CTR点击平台 学习前言 EasyRec仓库地址 DSSM实现思路 一 DSSM整体结构解析 二 网络结构解析 1 Embedding层的构建 2 网络层的构建 3 相似度计
  • 【毕业设计】深度学习验证码识别算法研究与实现 - python 机器视觉

    文章目录 0 简介 1 数据收集 2 识别过程 3 网络构建 4 数据读取 5 模型训练 6 加入Dropout层 7 数据增强 8 迁移学习 9 结果 9 最后 0 简介 Hi 大家好 这里是丹成学长的毕设系列文章 对毕设有任何疑问都可以
  • 测试老鸟总结,性能测试需求分析-性能必要性,一篇打通...

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • java中Optional使用方法

    Optional是Java 8中提供的一个容器类 用来装载可能为空的引用 在使用Optional时 不需要检查null 可以避免NullPointerException 1 创建Optional实例 Optional可以通过工厂方法of o
  • Linux下PostgreSQL主备环境搭建和切换

    1 概念 数据库热备 数据库热备是指为主数据库的创建 维护和监控一个或多个备用数据库 它们时刻处于开机状态 同主机保持同步 当主机失灵时 可以随时启用热备数据库来代替 以保护数据不受故障 灾难 错误和崩溃的影响 流复制 streaming