GPDB - 高可用 - 流复制状态

GPDB - 高可用 - 流复制状态

GPDB的高可用基于流复制,通过FTS进行自动故障切换。自动故障切换需要根据primary-mirror流复制的各种状态进行判断。本节就聊聊primary-mirror流复制的各种状态。同样适用于PgSQL

1、WalSndState

typedef enum WalSndState
{WALSNDSTATE_STARTUP = 0,WALSNDSTATE_BACKUP,WALSNDSTATE_CATCHUP,WALSNDSTATE_STREAMING,WALSNDSTATE_STOPPING
} WalSndState;

WalSndState保存的是wal sender进程的状态信息,变量值如上代码。

WALSNDSTATE_STARTUP表示启动状态;

WALSNDSTATE_BACKUP表示备份状态

WALSNDSTATE_CATCHUP表示追赶状态

WALSNDSTATE_STREAMING表示流复制状态

WALSNDSTATE_STOPPING表示wal sender即将退出

2、什么时候切换到WALSNDSTATE_STOPPING

7dbab5efbc05a70df25940770731115f.png

1)集群shutdown有三种方式:smart、fast、immediate

三种标记值分别为:

#define      SmartShutdown  1
#define      FastShutdown  2
#define      ImmediateShutdown  3

Smart shutdown:不允许有新连接,待已有连接全部结束后关闭数据库;

Fast shutdown:不允许新连接,向所有活跃的服务进程发送SIGTERM信号,让他们立即退出,之后等待所有子进程退出并关闭数据库

Immediate shutdown:不允许新连接,主进程postgres向所有子进程发送SIGQUIT信号并立即退出,所有子进程也会立即退出。下次启动会回放WAL日志进行恢复。

2)如果shutdown模式不为immediate,则集群shutdown的时候,postgres主进程会向checkpoint进程发送SIGUSR2信号:

db6c85466c40008fb0af11591280556a.png

3)checkpoint进程的SIGUSR2信号处理函数为ReqShutdownHandler,从上图的代码逻辑可见,ReqShutdownHandler会将shutdown_requested置为true,并唤醒MyLatch。

4)checkpoint进程接着调用ShutdownXLog,然后proc_exit(0)退出checkpoint进程。

5)ShutdownXLog函数调用WalSndInitStopping向所有sender进程发送SIGUSR1信号;然后调用WalSndWaitStopping等待所有sender进程退出,每个10ms判断一次。

6)sender进程SIGUSR1信号处理函数procsignal_sigusr1_handler检查信号来自PROCSIG_WALSND_INIT_STOPPING,然后将got_STOPPING置为true

7)流复制的sender处理完SIGUSR1信号后,继续返回信号前处理流程。Sender的发送日志函数为XLogSendPhysical,此时got_STOOPING已为true,所以调用WalSndSetState将walsnd->state切换到WALSNDSTATE_STOPPING状态,然后调用FTSReplicationStatusUpdateForWalState更新WAL复制状态

8)另外当sender进程从WalSndLoop退出后(replication_active置为false),这个时候,Wal sender进程才接收到信号,HandleWalSndInitStopping中也可以看到,会向自己发送SIGTERM信号,信号处理函数die,即退出进程(因为流复制终止了,不必管它了)。

9)若,sender进程还没从WalSndLoop退出(replication_active置为true),这个时候,Wal sender进程接收到信号,HandleWalSndInitStopping中也可以看到,他会设置got_STOPPING为true,让WAL sender进程发送完WAL后退出WalSndLoop循环后调用proc_exit自行退出。

2、sender进程什么时候退出?

书接上文,产生个问题:WalSndLoop何时退出?若没有shutdown,何时再发起流复制?

e41bd8fe918b5ad04bee525690261e3e.png

Wal sender进程接收到mirror发来的start replication命令后,进入StartReplication开始流复制。

1)WalSndLoop循环中,通过XLogSendPhysical函数不断发送WAL

2)XLogSendPhysical函数发送WAL达到一个时间线的末尾节点位置时,向mirror的receiver进程发送CopyDone消息,即开头为‘c’的消息,并将streamingDoneSending变量改为true

3)receiver进程的入口函数WalReceiverMain,通过walrcv_receive::libpqrcv_receive不断接收WAL日志和消息。当接收到发来的CopyDone消息后返回-1

4)接着,返回到WalReceiverMain函数中,当walrcv_receive返回-1后,一路下来会退出接收消息和日志的循环,并进入walrcv_endstreaming再向primary发送个CopyDone消息

5)primary的ProcessRepliesIfAny处理mirror发来的消息,当接收到CopyDone消息后,将streamingDoneReceiving改为true

6)返回WalSndLoop循环,当streamingDoneSending和streamingDoneReceiving都为true时退出循环

总结一句话:primary发完一个时间线内的WAL,切换下一个时间线时,会退出发送WAL日志的循环stop streaming;当然mirror的receiver进程发起下一个时间线的日志拉取,即再次调用libpqrcv_startstreaming函数向primary发送START_REPLICATION命令后,primary仍旧会再次进入WalSndLoop循环发送WAL日志。

3、什么时候进入WALSNDSTATE_BACKUP?

exec_replication_command:进行基础备份的时候

exec_replication_command:进行基础备份的时候switch (cmd_node->type){case T_BaseBackupCmd:PreventInTransactionBlock(true, "BASE_BACKUP");SendBaseBackup((BaseBackupCmd *) cmd_node);|  parse_basebackup_options(cmd->options, &opt);|  WalSndSetState(WALSNDSTATE_BACKUP);|  perform_base_backup(&opt);break;...}

进行基础备份,也就是构建mirror的时候进入该状态。

4、什么时候进入WALSNDSTATE_STARTUP?

1)sender进程刚fork出来,InitWalSenderSlot初始化的时候

2)WalSndLoop进程退出后又进入startup状态,因为下个时间线的复制即将开始

3)sender进程遇到ERROR故障,跳回到PostgresMain回退操作处,回退事务后,进入WalSndErrorCleanup,若没有stop则重新设置为startup状态,等待接收start replication命令重新开始复制。

PostgresMainif (am_walsender)InitWalSender();//sender进程的初始化|--  InitWalSenderSlot|--  for (i = 0; i < max_wal_senders; i++){|    WalSnd     *walsnd = &WalSndCtl->walsnds[i];|    SpinLockAcquire(&walsnd->mutex);|    if (walsnd->pid != 0){|      //找一个空闲的slot|      SpinLockRelease(&walsnd->mutex);|      continue;|    }else{|      walsnd->pid = MyProcPid;|      walsnd->state = WALSNDSTATE_STARTUP;|      ...|      break;|    }|  }|--  on_shmem_exit(WalSndKill, 0);
StartReplication:sender的WalSndLoop退出后又进入startup状态WalSndLoop(XLogSendLogical);...if (got_STOPPING)proc_exit(0);WalSndSetState(WALSNDSTATE_STARTUP);EndCommand("COPY 0", DestRemote);
PostgresMain//sender进程遇到ERROR报错,sender进程需要再次start replication才能进入传输walif (sigsetjmp(local_sigjmp_buf, 1) != 0){AbortCurrentTransaction();if (am_walsender)WalSndErrorCleanup();|--  if (got_STOPPING || got_SIGUSR2)|    proc_exit(0);|--  WalSndSetState(WALSNDSTATE_STARTUP);...for (;;){firstchar = ReadCommand(&input_message);switch (firstchar){case 'Q':{if (am_walsender){if (!exec_replication_command(query_string))exec_simple_query(query_string);}else if (am_ftshandler)HandleFtsMessage(query_string);else if (am_faulthandler)HandleFaultMessage(query_string);elseexec_simple_query(query_string);send_ready_for_query = true;break;}case 'M': ...}}

5、什么时候进入WALSNDSTATE_CATCHUP?

开始流复制前,设置成catchup状态。

StartReplication:开始流复制前WalSndSetState(WALSNDSTATE_CATCHUP);/* Send a CopyBothResponse message, and start streaming */pq_beginmessage(&buf, 'W');pq_sendbyte(&buf, 0);pq_sendint16(&buf, 0);pq_endmessage(&buf);pq_flush();WalSndLoop(XLogSendLogical);...

6、什么时候进入WALSNDSTATE_STREAMING?

当前时间线内没有要发送的日志了,并且没有下一个时间线需要切换发送日志,则将其改为streaming状态。

WalSndLoopfor (;;){if (!pq_is_send_pending())send_data();elseWalSndCaughtUp = false;...//现在没有要发送的了if (WalSndCaughtUp && !pq_is_send_pending()){if (MyWalSnd->state == WALSNDSTATE_CATCHUP)WalSndSetState(WALSNDSTATE_STREAMING);}...}

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

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

相关文章

04-微服务-Nacos

Nacos注册中心 国内公司一般都推崇阿里巴巴的技术&#xff0c;比如注册中心&#xff0c;SpringCloudAlibaba也推出了一个名为Nacos的注册中心。 1.1.认识和安装Nacos Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在…

MySQL-存储引擎

简介&#xff1a;存储引擎是存储数据&#xff0c;建立索引&#xff0c;更新/查询数据等技术的实现方式。存储引擎是基于表的&#xff0c;而不是基于库的&#xff0c; (同一个数据库的不同表可以选择不同的存储引擎) 所以存储引擎也可被称为表类型。 我们输入 SHOW CREATE TAB…

Halcon机器视觉和运动控制软件通用框架,24年1月最新版新增UI设计器,插件式开发,开箱即用 仅供学习!

24年1月更新 下载点我 此版本已经添加ui设计器。具体功能如上所示&#xff0c;可以自定义变量&#xff0c;写c#脚本&#xff0c;自定义流程&#xff0c;包含了halcon脚本和封装的算子&#xff0c;可自定义ui&#xff0c;通过插件形式开发很方便拓展自己的功能。 ui设计器

消息队列-RocketMQ-概览与搭建

RocketMQ 领域模型 RockeMQ整体结构预览 RocketMQ 中的一些概念 Topic&#xff1a;主题&#xff0c;可以理解为类别、分类的概念 MessageQueue&#xff1a;消息队列&#xff0c;存储数据的一个容器&#xff08;队列索引数据&#xff09;&#xff0c;默认每个 Topic 下有 4 个队…

树莓派ubuntu:默认分辨率太小图形界面中无法修改,如何设置分辨率

树莓派安装ubuntu后&#xff0c;连接外接7寸显示屏(1024x)&#xff0c;只显示720分辨率内容显示不全&#xff0c;按如下方式设置&#xff1a; 修改 /boot/config.txt文件 使用pc读卡器读写sd卡 直接命令读写配置文件 sudo nano /boot/config.txtconfig.txt结尾追加如下内容 …

AI担任编程导师:生成式AI如何翻江倒海改变开发世界

生成式 AI 如何重塑开发流程和开发工具&#xff1f; 在21世纪的舞台上&#xff0c;AI作为技术明星&#xff0c;一直以其潜力无穷的表现吸引着我们的目光。而其中&#xff0c;一名角色&#xff0c;响亮的名字叫做生成式AI&#xff0c;正在以翩翩起舞的姿态&#xff0c;改变着我…

华为mstp、vrrp、ospf、isis、bgp等综合一起排错

最终实现左边私网和右边私网全部ping通 SW1 vlan batch 12 34 stp region-configuration //mstp配置 region-name test instance 12 vlan 12 instance 34 vlan 34 active region-configuration interface GigabitEthernet0/0/3 port link-type trunk port trunk allow-pass …

HCIA-Datacom题库(自己整理分类的)_05_园区网和网络架构多选【6道题】

1.以下哪些网络属于局域网&#xff1f; 一个家庭网络 宽带城域网 某公司办公网络 因特网 2.下列关于单臂路由的说法正确的有&#xff1f; 每个VLAN一个物理连接 在路由器上需要创建子接口 交换机上&#xff0c;把连接到路由器的端口配置成Trunk类型的端口&#xff0c;并…

Windows11 - Ubuntu 双系统及 ROS、ROS2 安装

系列文章目录 前言 一、Windows11 - Ubuntu 双系统安装 硬件信息&#xff1a; 设备名称 DESKTOP-B62D6KE 处理器 13th Gen Intel(R) Core(TM) i5-13500H 2.60 GHz 机带 RAM 40.0 GB (39.8 GB 可用) 设备 ID 7673EF86-8370-41D0-8831-84926668C05A 产品 ID 00331-10000-0000…

常见服务/协议默认端口号、HTTP状态码

文章目录 1. 默认端口号2. Http状态码2.1 1xx&#xff08;临时响应&#xff09;&#xff1a;2.2 2xx&#xff08;成功&#xff09;&#xff1a;2.3 3xx&#xff08;重定向&#xff09;&#xff1a;2.4 4xx&#xff08;客户端错误&#xff09;&#xff1a;2.5 5xx&#xff08;服…

(低级错误)IDEA/Goland报错连接数据库失败:URL错误和权限问题。

前言 做毕设ing&#xff0c;使用Goland自带的数据库工具连接服务器的数据库。报错 错误: Malformed database URL, failed to parse the main URL sections. (view)服务器是华为云&#xff0c;使用宝塔面板。数据库版本5.6.50。 排查过程 鉴于Goland报错报的狗屁不是&#…

【通义千问】大模型Qwen GitHub开源工程学习笔记(5)-- 模型的微调【全参数微调】【LoRA方法】【Q-LoRA方法】

摘要: 训练数据的准备 你需要将所有样本放到一个列表中并存入json文件中。每个样本对应一个字典,包含id和conversation,其中后者为一个列表。示例如下所示: [{"id": "identity_0","conversations": [{"from": "user",…

【MySQL】视图,外连接内连接子查询简单介绍及面试笔试案例题

目录 一 视图 1.1视图是什么 1.2 创建视图 1.3 查看视图(两种) 1.4 修改视图(两种) 1.5 删除视图 二 外连接&内连接&子查询介绍 2.1 外连接 2.2 内连接 2.3 子查询 三 外连接&内连接&子查询案例 3.1 了解表结构与数据 3.2 案例题目 四 思维导图…

qt第三天快速回顾

控件 listWidget 两种添加方式 1QListWidgetItem 2QStringList(链式编程) TreeWidget 核心代码 1设置头的标签 2.Item创建 添加顶层级别的Item 3.创建子Item 挂载到顶层的Item上 QLabelWidget 表格 增加了一个删除和添加 1.设…

【算法Hot100系列】合并 K 个升序链表

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

不同像平面坐标系下的Brown畸变系数互转

不同像平面坐标系下Brown畸变系数转换 记 u , v u,v u,v为像素为单位的坐标&#xff0c;f为焦距&#xff0c;单位也是像素。 记 x , y x,y x,y为理想坐标。本文推导两种情况下的Brown畸变系数转换关系&#xff1a; 相同坐标系定义、不同的坐标单位&#xff08;像素坐标与归一…

RocketMQ源码 事务消息 TransactionalMessage 源码分析

前言 原理&#xff1a;使用普通消息和订单事务无法保证一致的原因&#xff0c;本质上是由于普通消息无法像单机数据库事务一样&#xff0c;具备提交、回滚和统一协调的能力。 而基于 RocketMQ 的分布式事务消息功能&#xff0c;在普通消息基础上&#xff0c;支持二阶段的提交能…

2023年全国职业院校技能大赛软件测试赛题第2套—自动化测试报告解析答案

2023年全国职业院校技能大赛软件测试赛题任务五自动化测试 一、自动化测试任务要求 题目1:按照以下步骤在PyCharm中进行自动化测试脚本编写并执行。 1. 设置智能时间等待5秒并将浏览器窗口最大化; 2. 引入By方法类; 3. 通过NAME属性定位用户名输入框,并输入用户名XTGL…

论正确初始化深度学习模型参数的重要性

遇到的问题&#xff1a;在一般的深度学习训练过程中&#xff0c;我们建立好模型以后&#xff0c;程序就有自动的初始化一些模型的参数&#xff0c;比如全连接层中每一个节点的权重等等&#xff0c;在之前的网络训练过程中&#xff0c;我总是事先设下随机种子以后&#xff0c;让…

像专家一样使用TypeScript映射类型

掌握TypeScript的映射类型&#xff0c;了解TypeScript内置的实用类型是如何工作的。 您是否使用过Partial、Required、Readonly和Pick实用程序类型? 你知道他们内部是怎么运作的吗? 如果您想彻底掌握它们并创建自己的实用程序类型&#xff0c;那么不要错过本文所涵盖的内容。…