亚信安慧AntDB数据库分布式架构剖析之snapshot receiver进程

本文主要介绍亚信安慧AntDB数据库的分布式架构下的特有进程之snapshot receiver的设计,这也是分布式架构的核心进程之一

进程简介

该进程的作用从逻辑上解释包含两个方面:

  • 同步快照,并且是作为通信的client端存在

  • 同步事务号,同样也是client端(

与此同时,该进程只存在于Coordinator节点(后文简称CN节点)和Datanode节点(后文简称DN节点)上,且主机和备机上都有,这些节点上有且仅有一个该进程。

(注:通信的server端则是snapshot sender进程,这部分内容笔者将会在另一篇文章中阐述)

进程的内存结构

Snapshot receiver进程在物理上并没有特别的文件存储方式,启动进程时同时会申请共享内存,所有的数据都在这部分内存之中。

内存结构名为SnapRcvData,代码内通常以SnapRcv指针来访问这部分内存,完整的结构体定义较为琐碎,为了便于读者理解,这里仅挑选部分重要的内容给出说明,完整的定义参考源码文件(src/backend/replication/snapreceiver.c):

  • mutex:访问这部分共享内存时要加的锁

  • gxid_mutex:访问事务号成员时要加的锁

  • geters:backend进程等待申请事务号时的队列,等待receiver进程响应申请事务号的请求

  • reters:已获取事务号的backend队列,等待backend取走事务号

  • xcnt:当前集群内活跃事务号的个数

  • xip[MAX_BACKENDS]:当前集群内活跃事务号的列表

  • wait_finish_cnt:本节点申请的事务号个数,仅CN节点会有这个值

  • wait_xid_finish[MAX_BACKENDS]:本节点申请的事务号列表,仅CN节点会有这个值

  • latestCompletedXid:当前集群内最大的已完成的事务号

  • global_xmin:当前集群内的xmin(分布式集群内最老的活跃事务号)

  • local_global_xmin:本节点内的xmin(当前节点内最老的活跃事务号)

  • global_finish_id:本节点最近一次完成的事务号

进程的通信协议

“通信”特指与snapshot sender进程之间的通信,这里借用了逻辑复制的通信格式,采用了‘libpqwalreceiver’库的接口,使用到的接口的代码如下(src/backend/replication/libpqwalreceiver/libpqwalreceiver.c):

  • walrcv_connect

  • walrcv_disconnect

  • walrcv_startstreaming

  • walrcv_send

  • walrcv_receive

  • walrcv_get_senderinfo

不难看出,各接口的用途与名称有一定的必然联系,首先是建连,然后开始流复制,并通过send和receive传输数据。当snapshot receiver进程启动时,会主动连接snapshot sender进程,处理过程如下图所示:

图片

图1:snapshot receiver进程启动处理过程

建连成功之后会调用walrcv_startstreaming,把一些流复制选项同步到服务端,当服务端确认之后就会切换为copy-both模式,这时即表示可以正式传输数据了。当然,snapshot receiver进程同步的内容并不是流复制相关内容,而是事务号相关的内容,包括以下两个方面:

  • 下一个待分配的事务号(nextFullXid)

  • 本节点残留的2pc事务号列表,如果没有即为空(

注:这部分属于进程的异常处理逻辑,笔者会在后续的文章中专题剖析

建连完毕之后,进程即进入正式的通信阶段,一般来说,进入这个阶段集群基本已经启动完毕了,receiver和sender之间通过不同的消息类型去完成不同场景的需求,下面逐个介绍receiver进程的通信逻辑:

  • 消息‘a’

负责处理sender进程的广播消息,消息内容是其他CN申请的事务号,其接口是SnapRcvProcessAssign,处理步骤大致如下:

1、锁住共享内存(SnapRcv)

2、从消息流获取xid,然后遍历SnapRcv->xip数组,做去重处理,然后放入该数组内,同时SnapRcv->xcnt加1

3、解锁

4、如果新的xid大于等于本地的ShmemVariableCache->nextFullXid,并且不是备节点,就需要扩展新的clog,同时更新nextFullXid

  • 消息‘g’                                    

负责处理申请事务号后sender进程反馈回来的数据,其接口是SnapRcvProcessAssignRequest,处理步骤大致如下:                     

1、锁住共享内存(SnapRcv)

2、从消息流获取xid和procno,然后遍历SnapRcv->reters队列,找出正在等待事务号的进程对应的procno

3、找到进程之后,xid赋值给proc->getGlobalTransaction

4、然后setlatch,通知backend进程,backend进程会取出proc->getGlobalTransaction返回给上层调用

5、解锁           

  • 消息‘c’                                     

负责处理sender进程的广播消息,消息内容是其他CN结束的事务号,其接口是SnapRcvProcessComplete,处理步骤大致如下:

1、锁住共享内存(SnapRcv)

2、从消息流获取xid,然后遍历SnapRcv->xip数组,若找到就把这个xid从该数组内删除,同时SnapRcv->xcnt减1;如若没找到,会报ERROR

3、同时,如果该xid大于SnapRcv->latestCompletedXid,那就更新SnapRcv->latestCompletedXid的值

4、唤醒正在等待该事务提交的backend进程

5、解锁

6、用最新的SnapRcv->latestCompletedXid值来更新本地的ShmemVariableCache->latestCompletedXid

                                   

  • 消息‘f                                  

负责处理结束事务号后sender进程反馈回来的数据,其接口是SnapRcvProcessFinishRequest,处理步骤大致如下:

1、锁住共享内存(SnapRcv)

2、从消息流获取xid和procno,然后遍历SnapRcv->wait_commiters队列,找出正在等待的进程对应的procno和xid

3、找到进程之后,proc->getGlobalTransaction的值恢复为InvalidTransactionId

4、然后setlatch,通知backend进程

5、解锁

  • 消息‘s’                                     

负责处理sender进程同步来的快照数据,其接口是SnapRcvProcessSnapshot,处理步骤大致如下:

1、从消息流获取快照、xmin和latestCompletedXid三份数据

2、锁住共享内存(SnapRcv)

3、用gtm传来的值更新SnapRcv->latestCompletedXid

4、把快照数据整体memcpy到SnapRcv->xip数组

5、唤醒等待中的进程

6、解锁

7、更新SnapRcv->global_xmin(这个值在backend获取快照时,用于更新snapshot->global_xmin)

  • 消息‘h’                                    

处理心跳消息的反馈,其接口是SnapRcvProcessHeartBeat,处理步骤大致如下:

1、接收的心跳包内包含2个内容,时间戳和xmin

2、接收到心跳之后,更新SnapRcv->gtm_delta_time和SnapRcv->global_xmin

相对应的,还有一个发送心跳包的接口为SnapRcvSendHeartbeat,这个并不是‘h’消息的处理内容,而是SnapReceiverMain主函数的流程,处理步骤大致如下:

1、每次循环到对应的处理阶段(参考图2的流程),判断当前时间是否超过了设定的心跳间隔时间阈值(snap_receiver_timeout),这个是guc参数,默认60s 

2、 如果超过了阈值,就发送心跳包,否则跳过

3、发送的内容同接收一样,时间戳和xmin

  • 消息‘u’                                    

sender进程会通过这个消息,把nextFullXid同步到所有其他节点,其接口是SnapRcvProcessUpdateXid,处理步骤如下:

1、sender发来的只有一个事务号,即nextFullXid(下一个待分配的事务号)

2、如果拿到的xid比本地ShmemVariableCache->nextFullXid的要大,就更新ShmemVariableCache->nextFullXid和ShmemVariableCache->latestCompletedXid

3、最后更新SnapRcv->latestCompletedXid(先锁后更新)

进程的工作主流程

Snapshot receiver进程整体上同其他辅助进程相类似,启动之后会处于一个无限循环之中,不断监听各种事件和信号,笔者整理了一份流程图帮助读者理解,如下图所示:

图片

图 2:Snapshot receiver进程工作主流程图

上述流程图对应的既是SnapReceiverMain函数,又是snapshot receiver进程的主函数,之前的各种消息处理都是从这里开始的,想深入理解各种细节的读者可以从这里入手。

小结

本文介绍了snapshot receiver进程在正常情况下的处理逻辑,通过流复制协议,配合以不同的消息处理函数,完成了分布式事务号、分布式快照的同步功能。一个进程不可能总是处于正常状态,那当异常发生时,AntDB如何来保证事务的一致性呢?敬待后续的专题分享。

关于亚信安慧AntDB数据库

AntDB数据库始于2008年,在运营商的核心系统上,服务国内24个省市自治区的数亿用户,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔通信核心交易,保障系统持续稳定运行超十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。

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

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

相关文章

循环购模式玩法,贡献值能量值助力可持续发展

​小编介绍:10年专注商业模式设计及软件开发,擅长企业生态商业模式,商业零售会员增长裂变模式策划、商业闭环模式设计及方案落地;扶持10余个电商平台做到营收过千万,数百个平台达到百万会员,欢迎咨询。 循…

EPSON 精致小巧的32.768KHz晶振广泛用于时钟模块

32.768K晶振在电子主板PCB随处可见,32.768K晶振负责为各种计算机,控制器,微处理器等提供高精度的时钟频率,而在这些晶振中,32.768KHz贴片时钟晶振特别重要,因为它不仅被广泛应用于电子设备中,而且还有着小巧,低功耗的优点,32.768KHz贴片时钟晶振在现代电子设备中应用广泛,如计算…

el-table的border属性失效问题解决方案

目录 问题: 使用的代码: 官方文档的说明: 可能的问题所在: 关于使用了作用域插槽: a.自定义内容的样式覆盖: b.表格结构的改变: 解决方案: 通过css样式解决: 下面…

[江苏工匠杯]easyphp

先看源码 <?php highlight_file(__FILE__); $key1 0; $key2 0; ​ $a $_GET[a]; $b $_GET[b]; ​ if(isset($a) && intval($a) > 6000000 && strlen($a) < 3){if(isset($b) && 8b184b substr(md5($b),-6,6)){$key1 1;}else{die("…

C语言中大小写字母如何转化

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

【办公类-40-01】20240311 用Python将MP4转MP3提取音频 (家长会系列一)

作品展示&#xff1a; 背景需求&#xff1a; 马上就要家长会&#xff0c;我负责做会议前的照片滚动PPT&#xff0c;除了大量照片视频&#xff0c;还需要一个时间很长的背景音乐MP3 一、下载“歌曲串烧” 装一个IDM 下载三个“串烧音乐MP4”。 代码展示 家长会背景音乐: 歌曲串…

C++ 拷贝构造函数和运算符重载

目录 一. 拷贝构造函数 1. 引入 2. 拷贝构造的概念 3. 浅拷贝 4. 深拷贝 二. C运算符重载 1. 概念 2. 注意事项 3.举例 一. 拷贝构造函数 1. 引入 我们在创建对象时&#xff0c;能不能创建一个与原先对象一模一样的新对象呢&#xff1f;为了解决这个问题&#x…

0304_数据可视化实战(一)

数据处理 安装openpyxl # 当前执行的命令是安装在该虚拟python环境中 !pip install openpyxl -i https://mirrors.aliyun.com/pypi/simple/数据查看 import pandas as pd fund pd.read_excel(./fund.xlsx) # 查看前10条数据 fund.head(10)姓名公司基金数量年天基金规模基金…

Windows系统搭建Cloudreve结合内网穿透打造可公网访问的私有云盘

目录 ⛳️推荐 1、前言 2、本地网站搭建 2.1 环境使用 2.2 支持组件选择 2.3 网页安装 2.4 测试和使用 2.5 问题解决 3、本地网页发布 3.1 cpolar云端设置 3.2 cpolar本地设置 4、公网访问测试 5、结语 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff…

1.leetcode---字符串中的第一个唯一字符(Java版)

链接在此: https://leetcode.cn/problems/first-unique-character-in-a-string/description/ 给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返回它的索引 。如果不存在&#xff0c;则返回 -1 。 示例 1&#xff1a; 输入: s “leetcode” 输出: 0…

阿里云 云盘扩容之后“不生效”处理办法

服务器只有一块40GB的系统盘&#xff08;/dev/vda1&#xff09;&#xff0c;目前已扩容到50GB&#xff0c;但是查看磁盘占用&#xff0c;还是没有变化 df -h [rootiZbp19utuqn2ezs6yevameZ www]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 868M…

三个表联合查询的场景分析-场景1:a表关联了b表和c表

本场景对应情景如下&#xff1a; 三个数据表&#xff0c;一个表的两个字段分别关联了另外两个表各自的id数据&#xff0c;可能包含多个id&#xff08;两个1对多关联&#xff09;。 目录 数据表准备 需求1、查询c表的列表数据&#xff0c;要求获得关联的b表中的name&#xf…