学习 PostgreSQL 流复制

PostgreSQL 流复制

PostgreSQL数据库异常中止后,数据库刚重启时,会重放停机前最后一个checkpoint点之后的 WAL日志,在把数据库恢复到停机的状态后,自动进入正常的状态,可以接收其他用户的查询和修改。

想象另一个场景:如果A机器上的数据库停止后,把A机器上的数据库整个拷贝到另一台机器B上,在机器B上启动这个数据库时,机器B上的数据库也将做与A机器上数据库重启时相同的事,即重放停止之前最后一个checkpoint点之后的 WAL日志,把数据库推导到停机时的状态。通常数据库完成恢复后会自动进入正常状态,如果有办法让这个数据库不自动进入正常状态,而是让其一直等待新的 WAL日志,如果有新的 WAL日志来则自动进行重放,直到主库失败后,再让B机器上的数据库进入正常状态,这样B机器上的数据库就成了-个 Standby 数据库,实现了当A机器上的数据库出故障时,B机器上的数据库能接管的功能。

PostgreSQL的流复制是异步的,异步的缺点是Standby上的数据落后于主库上的数据如果使用做读写分离,就会存在数据一致性的问题,这对于一些一致性较高的应用来说是不可接受的。所以 PostgreSQL从9.1版本之后提供了同步流复制的架构。同步复制要求在数据写入 Standby数据库后,事务的commit才返回,所以 Standby库出现问题时,会导致主库被hang住。解决这个问题的方法是启动两个 Standby数据库,这两个 Standby 数据库只要有一个是正常的,就不会让主库hang住。所以在实际应用中,同步流复制,总是有1个主库和2个以上的 Standby 库。

1、一主一备

主库配置

# postgresql.conf
wal_level='replica'
archive_mode='on'
archive_command='test ! -f /home/postgres/archive/%f && cp %p /home/postgres/archive/%f'
max_wal_senders=10      #可以有多少个流复制链接
wal_keep_size=128MB
wal_sender_timeout=60s  #流复制发送主机的超时时间。

# pg_hba.conf 
host    replication   repuser   0.0.0.0/0   password

完成以上准备工作后,就可以使用pg_basebackup命令行工具在备机机器上生成基础备份了,命令如下:

pg_basebackup -h 192.168.2.204 -p 1622 -U repuser -W -X stream -F p -P -R -D /home/postgres/pgdata -l backup20250207

完成启动备库,此时就建立好主备了。

默认是异步模式 async

图片
注意:只要主库中synchronous_standby_names参数中没有的名字,均为异步

下面我们给他调整成同步模式 sync

主库 添加参数 vim postgresql.conf

#synchronization level
synchronous_commit = on            #同步提交
synchronous_standby_names='node2'  #同步提交名字


备库 修改参数 vim postgresql.auto.conf,添加到配置文件的最后

application_name=node2

主、备 重启服务

psql -c "select application_name,client_addr,sync_state from pg_stat_replication;"

调整成sync同步模式

pg_stat_replication 试图中 sync_state 的三个值及其含义

1. async(异步)从节点以异步模式运行。这意味着主节点不会等待从节点确认事务已经应用,而是直接提交事务。
2. potential(潜在同步)从节点当前处于潜在同步状态。这意味着如果当前的同步从节点失效,这个从节点将被提升为同步从节点。
3. sync(同步)从节点以同步模式运行。这意味着主节点会等待从节点确认事务已经应用后才提交事务。这确保了更高的数据一致性和高可用性。

pg_stat_replication视图主要参数

psql -xc "select * from pg_stat_replication;"
startup连接中,catchup同步中 streaming 同步
sent_lsn    主库传送wal的位置
write_lsn   从库接收wal的位置
flush_lsn   从库同步到磁盘的wal位置
replay_lsn  从库同步到数据库的wal位置
write_lag   延迟
sync_priority 异步,1~x同步越小,同步级别越高
sync_state async 异步,sync同步,potential现在是异步,但可能升级为同步

2、一主两备

优点:前面说到,同步复制要求在数据写入 Standby数据库后,事务的commit才返回,所以 Standby库出现问题时,会导致主库被hang住。启动两个 Standby数据库,这两个 Standby 数据库只要有一个是正常的,就不会让主库hang住。

pg_basebackup -h 192.168.2.204 -p 1622 -U repuser -W -X stream -F p -P -R -D /home/postgres/pgdata -l backup20250207


修改参数 vim postgresql.auto.conf,添加到配置文件的最后

并不需要重启主库,只需要重新装载配置即可

pg_ctl reload
psql -c "select application_name,client_addr,sync_state from pg_stat_replication;"
  1. 两个备库一个同步以一个异步,我们来shutdown node2.测试能否提交数据

主节点可以正常提交

2) 我们把两个节点都升级为同步模式,修改配置

#synchronization level
synchronous_commit = on                  #同步提交
synchronous_standby_names='node2,node3'  #同步提交名字

可以看到node3 备设置为potential(潜在同步)

此时我们关闭node2,可以看到 node3 由 potential 升级为 sync

数据可以正常写入

b.此时我们关闭node2,node3,主库会等待,只要一个备库正常,即可提交成功


可以看到node2的优先级是1,node3的优先级是2这个优先级是由synchronous_standby_names 参数配置的顺序决定的。目前主数据库与db02处于同步“sync”,而 node3 的状态为potential”,表示它是一个潜在的同步 Standby,当node2损坏时,node3 会切换到同步状态。

psql -c "select application_name,client_addr,sync_priority,sync_state from pg_stat_replication;"


在PG10及以后版本中,引入了 synchronous_standby_names 这种基于** Quorum**的同步复制优选提交的机制。

同步复制支持一个或者更多个同步后备服务器,事务将会等待,直到所有同步后备服务器都确认收到了它们的数据为止。事务必须等待其回复的同步后备的数量由synchronous_standby_names 指定。这个参数还指定一个后备服务器名称及方法(FIRST和ANY)的列表来从列出的后备中选取同步后备。

方法FIRST 指定一种基于优先的同步复制并且让事务提交等待,直到它们的WAL记录被复制到基于优先级选中的所要求数量的同步后备上为止。在列表中出现较早的后备被给予较高的优先级,并且将被考虑为同步后备。其他在这个列表中位置靠后的后备服务器表示可能的同步后备。如果任何当前的同步后备由于任何原因断开连接,它将立刻被下一个最高优先级的后备所替代。

配置1:如果有多台备node1、node2、node3、node4正在运行,事务提交将会等待来其中中至少任意一台备机器的回复,才能提交成功。node4 是一台异步后备,因为它的名字不在该列表中。

synchronous_standby_names='ANY 1 (node1,node2,node3)'

配置2:如果有多台备node1、node2、node3、node4正在运行,事务提交将会等待来其中中至少任意两台备机器的回复,才能提交成功。node4 是一台异步后备,因为它的名字不在该列表中

synchronous_standby_names='ANY 2 (node1,node2,node3)'

配置3:node1,node2 将被选中为同步备库,主库提交事务时,node1,node2 都写入wal才能提交成功。如果 node1,node2 任意一个失效,node3,node4 可以升级为同步备库。

synchronous_standby_names = 'FIRST 2 (node1,node2,node3,node4)'

注意:
如果在提交正在等待确认时主服务器重启,那些正在等待的事务将在主数据库恢复时被标记为完全提交。没有办法确认所有后备服务器已经收到了在主服务器崩溃时所有还未处理的 WAL 数据。某些事务可能不会在后备服务器上显示为已提交,即使它们在主服务器上显示为已提交。我们提供的保证是:在 WAL 数据已经被所有后备服务器安全地收到之前,应用将不会收到一个事务成功提交的显式确认。

判断是否为备库

postgres=# select pg_is_in_recovery();
 pg_is_in_recovery
-------------------
 f
f:主库,t:备库

======================================================
文章参考:唐成老师PostgreSQL修炼之道从小工到专家

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

macbook2015升级最新MacOS 白苹果变黑苹果

原帖:https://www.bilibili.com/video/BV13V411c7xz/MAC OS系统发布了最新的Sonoma,超酷的动效锁屏壁纸,多样性的桌面小组件,但是也阉割了很多老款机型的升级权利,所以我们可以逆向操作,依旧把老款MAC设备强…

2025年最新版武书连SCD期刊(中国科学引文数据库)来源期刊已更新,可下载PDF版!需要的作者进来了解~

2025年最新版武书连SCD期刊(中国科学引文数据库)来源期刊已更新! 官网是不提供免费查询的。小编给大家两个路径,无需下载PDF,随时随地都能查25版SCD目录。 路径一:中州期刊联盟官网,25版SCD目…

deepseek大模型集成到idea

1 下载插件 安装CodeGPT打开 IntelliJ IDEA,鼠标点击左上角导航栏,File --> Setting 2 申请API key 3 配置deepseek 在 Settings 界面中的搜索框中,搜索 CodeGPT,路径 Tools --> CodeGPT --> Providers --> 如下一…

本地部署DeepSeek,并使用UI界面进行快速交互

一.需要本地部署的原因 1.我们在deepseek的官网界面进行交互时,经常会出现如下问题,不能正常交互,很是困扰: 2.本地部署的好处 就是能够很流畅的与deepseek进行交互;也有缺点,现在官网交互的版本更高一点…

8.flask+websocket

http是短连接,无状态的。 websocket是长连接,有状态的。 flask中使用websocket from flask import Flask, request import asyncio import json import time import websockets from threading import Thread from urllib.parse import urlparse, pars…

深度学习之神经网络框架搭建及模型优化

神经网络框架搭建及模型优化 目录 神经网络框架搭建及模型优化1 数据及配置1.1 配置1.2 数据1.3 函数导入1.4 数据函数1.5 数据打包 2 神经网络框架搭建2.1 框架确认2.2 函数搭建2.3 框架上传 3 模型优化3.1 函数理解3.2 训练模型和测试模型代码 4 最终代码测试4.1 SGD优化算法…

【Matlab优化算法-第15期】基于NSGA-II算法的铁路物流园区功能区布局优化

基于NSGA-II算法的铁路物流园区功能区布局优化 一、前言 铁路物流园区的合理布局对于提高物流效率、降低运营成本具有重要意义。随着铁路物流的快速发展,传统的铁路货场需要升级为综合物流园区,以满足多式联运和综合物流服务的需求。本文将介绍一种基于…

手写一个C++ Android Binder服务及源码分析

手写一个C Android Binder服务及源码分析 前言一、 基于C语言编写Android Binder跨进程通信Demo总结及改进二、C语言编写自己的Binder服务Demo1. binder服务demo功能介绍2. binder服务demo代码结构图3. binder服务demo代码实现3.1 IHelloService.h代码实现3.2 BnHelloService.c…

WebSocket connection failed 解决

WebSocket connection failed 解决 前言 这里如果是新手小白不知道 WebSocket 是什么的? 怎么使用的?或者想深入了解的 那可以 点击这里 几分钟带你快速了解并使用,已经一些进阶讲解; WebSocket,多应用于需要双向数据…

Python截图轻量化工具

一、兼容局限性 这是用Python做的截图工具,不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境; 如果要提升其跨平台性的话,需要考虑替换cty…

字节跳动后端一面

📍1. Gzip压缩技术详解 Gzip是一种流行的无损数据压缩格式,它使用DEFLATE算法来减少文件大小,广泛应用于网络传输和文件存储中以提高效率。 🚀 使用场景: • 网站优化:通过压缩HTML、CSS、JavaScript文件来…

Visual Studio踩过的坑

统计Unity项目代码行数 编辑-查找和替换-在文件中查找 查找内容输入 b*[^:b#/].*$ 勾选“使用正则表达式” 文件类型留空 也有网友做了指定,供参考 !*\bin\*;!*\obj\*;!*\.*\*!*.meta;!*.prefab;!*.unity 打开Unity的项目 注意:只是看&#xff0…

智慧机房解决方案(文末联系,领取整套资料,可做论文)

智慧机房解决方案-软件部分 一、方案概述 本智慧机房解决方案旨在通过硬件设备与软件系统的深度整合,实现机房的智能化管理与服务,提升机房管理人员的工作效率,优化机房运营效率,确保机房设备的安全稳定运行。软件部分包括机房管…

ubuntu中如何在vscode的终端目录后显示(当前的git分支名) 实测有用

效果展示 配置过程: 在 Ubuntu 中,如果你想在 VS Code 的终端提示符后显示当前的 Git 分支名,可以通过修改 Shell 配置文件(如 ~/.bashrc 或 ~/.zshrc)来实现。以下是具体步骤: 1. 确定使用的 Shell 首…

【机器学习案列】车辆二氧化碳排放量预测

这里是引用 🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中…

SpringCloud - Sentinel服务保护

前言 该博客为Sentinel学习笔记,主要目的是为了帮助后期快速复习使用 学习视频:7小快速通关SpringCloud 辅助文档:SpringCloud快速通关 源码地址:cloud-demo 一、简介 官网:https://sentinelguard.io/zh-cn/index.h…

基于 GEE 利用插值方法填补缺失影像

目录 1 完整代码 2 运行结果 利用GEE合成NDVI时,如果研究区较大,一个月的影像覆盖不了整个研究区,就会有缺失的地方,还有就是去云之后,有云量的地区变成空值。 所以今天来用一种插值的方法来填补缺失的影像&#xf…

海云安开发者智能助手(D10)全面接入DeepSeek,赋能开发者安全高效编码新范式

海云安正式宣布完成与DeepSeek(深度求索)的深度技术融合,旗下核心产品D10开发者智能助手全面接入DeepSeek R1模型。此次合作标志着海云安在"AI驱动开发安全"领域实现重要突破。数据显示,通过DeepSeek R1模型的优化与蒸馏…

Docker 1. 基础使用

1. Docker Docker 是一个 基于容器的虚拟化技术,它能够将应用及其依赖打包成 轻量级、可移植 的容器,并在不同的环境中运行。 2. Docker指令 (1)查看已有镜像 docker images (2)删除镜像 docker rmi …

【批量获取图片信息】批量获取图片尺寸、海拔、分辨率、GPS经纬度、面积、位深度、等图片属性里的详细信息,提取出来后导出表格,基于WPF的详细解决方案

摄影工作室通常会有大量的图片素材,在进行图片整理和分类时,需要知道每张图片的尺寸、分辨率、GPS 经纬度(如果拍摄时记录了)等信息,以便更好地管理图片资源,比如根据图片尺寸和分辨率决定哪些图片适合用于…