《PolarDB for PostgreSQL源码与应用实战》——PolarDB for PostgreSQL高可用原理(下)

简介: 《PolarDB for PostgreSQL源码与应用实战》——PolarDB for PostgreSQL高可用原理(下)

《PolarDB for PostgreSQL源码与应用实战》——PolarDB for PostgreSQL高可用原理(中) https://developer.aliyun.com/article/1232683?groupCode=polardbforpg


(三)一致性协议复制流程


下面我们看一下一致性协议复制的流程。


image.png


当PG进程需要提交WAL日志的时候,首先本地会写入WAL日志,然后开始等待提交LSN超过当前要提交的位点。提交了请求之后,我们会在两个链路上并行进行同步,在流复制链路上,它跟原生的逻辑其实是差不多的,它首先是通过WAL Sender来发送WAL日志,然后在Follower节点上由WAL Receiver接收,并持久化WAL日志。


在Consensus提交链路上,它主要流程是在Leader上,刚才也提到了由Append Thread根据当前的WAL日志回刷点来生成Consensus Log etnry,然后它需要把Consensus Log etnry写入本地,之后会传递给X-Paxos,开始发送到Follower节点。


在Follower节点上接收到Consensus Log之后,首先要确保所对应位点的WAL日志已经持久化成功了,确保之后就可以在本地写入Consensus Log,完成之后就可以回复Leader,表示本地已经持续化成功了。Leader节点会根据当前所有节点Consensus Log的持续化位点来确定当前最新的提交位点,之Advance线程会把提交位点转化成LSN,然后推进Commit LSN,再唤醒所有等待的PG进程。


正常的流程可能会比较简单一些,复杂的是当集群的状态、节点的状态发生变化的时候,应该如何进行协同处理,这个问题下文会阐述。


(四)Consensus日志存储


下面看一下Consensus日志的存储问题。


image.png


X-Paxos协议本身只负责日志的强一致同步,日志的持久化是通过API的方式由外部实现。

我们看一下在一致性协议中,X-Paxos内部有两类日志,首先是刚才提到由Append thread产生的,就是与日志同步本身相关的一些正常Log etnry。


从上文可以看到,这类日志本身除了一致性协议相关的一些信息,比如Term、 Log Index 、Type,还会自带一个CRC。


除了这些信息之外,它其实只是包含了当前所对应那段WAL日志的结束LSN,所以它的长度是固定的,这类日志在Consensus Log里面是占据了大多数。


第二类是X-Paxos协议,它本身会产生一些成员变更或者集群配置变更的日志,这些日志肯定是变长的,因为它里面要包含各个节点的配置信息,但是这个日志只占了非常小的一部分。所以在日志存储这方面,我们结合大部分日志都是固定长度的特点,采用了定长日志和变长日志混合存储。这个方案就是

在定长日志流中,对于定长日志它存储了完整的日志;变长日志只存储了它的偏移和长度,然后把变长日志的Payload,我们会在另外一个日志流里面存储。


在日志读取的时候,首先根据日志类型来确定是定长日志还是变长日志,如果是定长日志的话,就直接获取LSN信息,就可以获取到完整的信息。如果是变长日志,我们就根据日志中记录的偏移和长度去变长日志流里读取相应的内容。这样的好处是大部分情况下,当我们要获取定长日志的时候,可以直接通过Log Index定位日志所在的页面,以及这个页面上到底在哪个etnry,它的偏移是什么。


我们可以加速这个页面的定位,另外我们也引入了页面缓存,同时也引入了相关的一个LRU替换策略。


(五)Consensus状态机与DB状态机协同


介绍完日志复制的主要逻辑之后,接下来介绍如何根据X-Paxos内部Consensus的状态变化来推动DB状态的变化。


主动探测Consensus状态变化,触发Postmaster状态变更信号

Postmaster进程处理变更信号:


Slave:通知Startup进程Recovery状态变更,包括截断WAL日志、重建流复制或者升级等。

Master:降级则重启进入Recovery状态


image.png


首先,我们采用的方案是由Consensus进程主动探测X-Paxos层的状态变化,然后根据状态的变化产生一些变更的事件信号,然后通知Postmaster进行状态变更。如上图所示,左半部分是根据Consensus状态的状态变化产生事件,右边是DB侧收到这些信号之后,推进DB层的状态变化。


这会涉及到WAL日志对齐的问题,举个例子,比如发生了一个切主状态变化之后,如果Follower节点上从旧主库上拉取的WAL日志在新主库上不存在,那么当我们从新主库上重新去拉取WAL日志的时候,需要先充填掉多余的WAL日志。对于这一类状态变更,只有当日志对齐了之后,Consensus才能继续向前推进。


为了解决这个问题,我们给WAL日志也赋予了一个Term状态,也就是说只有当WAL日志的Term推进到最新之后,有相应的Term的Consensus log才能持久化,这样就能保证把上一个Term的WAL日志,多余的日志截断完成之后,下一个Term的Consensus Log才能持久化,否则根本不知道LSN对应的是一个上轮Term还是当前Term。除了刚才提到的WAL日志截断情况,在一致性协议里面,Consensus Log本身可能也会出现截断的情况。在这种情况下,本地的WAL日志也是需要被截断的。在以上两种情况下,WAL日志被截断之后,DB侧的一些数据状态,比如数据页面clog页面,这些应该如何处理?


首先,我们处理的策略主要包含三点。第一点是数据页面或者Clog页面在回刷磁盘持久化之前,必须要确保对应的WAL日志都已经在多数派上提交成功了,因为一旦持久化之后的状态肯定不会退,在一致性协议里面不会发生提交的状态、日志被截断。


另外一个点是在Follower节点上,只有当WAL日志在多数派上提交成功之后才开始回访。这个时候Follower节点上不管是缓存还是持久化的状态,其实都不可能出现回退的情况。


说到缓存,本身PG的机制是先修改比如说数据的Buffer,之后它会持久化WAL日志,所以可能当出现Leader降级之后,需要回退cache的情况,这里的处理逻辑是直接重启。因为此时需要从一个正常的读写状态进入到Recovery状态,目前PG里没有从读写状态进入到Recovery状态的逻辑,所以就直接重启再重新进入到Recover状态。


(六)双状态机协同-示例1


接下来会通过一个例子来具体介绍一下整个状态变更的过程。


image.png


比如当前是Follower状态,原来的状态如上图所示,每种状态是上半部分,下半部分是新的状态。


首先,比如Consensus进程探测到Term和Leader ID发生了变化,原来的Term是5,Leader ID是2,新的Term变成了6,新的Leader ID也变成了3。


当Consensus进程发现了这个状态变化之后,首先需要额外再获取当前Leader的信息,比如把ID转化成IP和Port,然后再获取一下当前Consensus Log的日志位点。获取到这些信息之后,就会直接去修改Postmaster的状态。修改完Postmaster状态之后,就给Postmaster发一个信号,然后Postmaster收到的信号事件,就是Leader发生了变化。Postmaster进程在收到这个信号之后,因为这个时候是Stream复制状态,所以需要去触发startup进程进行Recovery状态的变更。其中就会修改startup进程的recovery状态,比如还是保持Stream复制状态,becameLeader仍然是false,把Term变成6,再设置一下最新的Leader的IP和Port,其中也包含当前Consensus Log的位点。


修改完这个状态之后,就通知startup进程状态变更,然后startup进程本身会不断检测自己的Recovery状态,当发现Leader状态发生变化,会重启流复制,然后从新的Leader上拉取。比如刚才提到的可能会截断日志,这里不详细展开,有兴趣的话可以对照代码仔细看一下。


代码结构


(一)主要代码修改


上文介绍了一致性协议复制的原理和大体实现,接下来看一下相关的代码修改


image.png


主要包含以下几个方面,首先是一致性协议复制,第一部分是Consensus进程管理和提交主流程,第二部分是Consensus日志管理,比如日志的Append,日志根据Log Index的读取,都在Consensus日志管理文件里,第三部分是Consensus日志页面,就是具体缓存和持久化的相关管理。


第二块是流复制,主要包含两部分,第一部分是要收到包括从Consensus状态如何触发Postmaster的状态变化,然后Postmaste去触发startup进程的状态变化,主要是在xlog.c里。另外,流复制walsender和walreceiver这块也做了一些简单的修改,主要是在walsender.c和walreceiver.c文件里,大家可以去看一下。


另外,我们知道PG是C语言,X-Paxos是C++语言,所以这里需要相互的Wrapper。第一个是需要基于X-Paxos的相关接口提供一个c的Wrapper,另外日志管理这块是用C实现的,那么为了给X-Paxos使用,所以这块会提供日志管理接口的C++的Wrapper。


X-Paxos主要包含两部分,一个是算法的实现,就是在Libconsensus下面Consensus文件夹里,另外一块是X-Paxos本身依赖的高性能的网络编程框架,就是Libeasy。


最后一块是日志节点的实现,也就是Logger Syncer的功能,主要在polar_datamax.c这个文件里面,主要是如何驱动流复制的逻辑,其次是从Consensus状态变化,如何驱动Logger Syncer的状态变化。








相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
5月前
|
关系型数据库 MySQL 分布式数据库
安全可靠的PolarDB V2.0 (兼容MySQL)产品能力及应用场景
PolarDB分布式轻量版采用软件输出方式,能够部署在您的自主环境中。PolarDB分布式轻量版保留并承载了云原生数据库PolarDB分布式版技术团队深厚的内核优化成果,在保持高性能的同时,显著降低成本。
610 140
|
3月前
|
Cloud Native 关系型数据库 MySQL
免费体验!高效实现自建 MySQL 数据库平滑迁移至 PolarDB-X
PolarDB-X 是阿里云推出的云原生分布式数据库,支持PB级存储扩展、高并发访问与数据强一致,助力企业实现MySQL平滑迁移。现已开放免费体验,点击即享高效、稳定的数据库升级方案。
免费体验!高效实现自建 MySQL 数据库平滑迁移至 PolarDB-X
|
7月前
|
弹性计算 运维 关系型数据库
用 Patroni 搭建 PolarDB-PG 高可用集群
本文详细介绍了如何利用开源PolarDB-PG和Patroni搭建高可用集群。实验环境使用了三台ECS,内核版本为PolarDB-PG 15,Patroni版本为4.0.3,etcd版本为3.5.0。文章依次讲解了ETCD的安装与配置、PolarDB-PG 15的安装与初始化,以及Patroni的配置和启动过程。通过Patroni自动创建备库,实现高可用集群的搭建。最后总结指出,用户可根据需求调整配置,或选择线上PolarDB-PG产品以减少运维成本并提升稳定性。
|
3月前
|
关系型数据库 MySQL 分布式数据库
阿里云PolarDB云原生数据库收费价格:MySQL和PostgreSQL详细介绍
阿里云PolarDB兼容MySQL、PostgreSQL及Oracle语法,支持集中式与分布式架构。标准版2核4G年费1116元起,企业版最高性能达4核16G,支持HTAP与多级高可用,广泛应用于金融、政务、互联网等领域,TCO成本降低50%。
|
8月前
|
存储 关系型数据库 分布式数据库
|
6月前
|
关系型数据库 MySQL 分布式数据库
Super MySQL|揭秘PolarDB全异步执行架构,高并发场景性能利器
阿里云瑶池旗下的云原生数据库PolarDB MySQL版设计了基于协程的全异步执行架构,实现鉴权、事务提交、锁等待等核心逻辑的异步化执行,这是业界首个真正意义上实现全异步执行架构的MySQL数据库产品,显著提升了PolarDB MySQL的高并发处理能力,其中通用写入性能提升超过70%,长尾延迟降低60%以上。
|
7月前
|
存储 Cloud Native 关系型数据库
PolarDB开源:云原生数据库的架构革命
本文围绕开源核心价值、社区运营实践和技术演进路线展开。首先解读存算分离架构的三大突破,包括基于RDMA的分布式存储、计算节点扩展及存储池扩容机制,并强调与MySQL的高兼容性。其次分享阿里巴巴开源治理模式,涵盖技术决策、版本发布和贡献者成长体系,同时展示企业应用案例。最后展望技术路线图,如3.0版本的多写多读架构、智能调优引擎等特性,以及开发者生态建设举措,推荐使用PolarDB-Operator实现高效部署。
411 4
|
7月前
|
Cloud Native 关系型数据库 分布式数据库
PolarDB开源:云原生数据库的新篇章
阿里云自研的云原生数据库PolarDB于2023年5月正式开源,采用“存储计算分离”架构,具备高性能、高可用及全面兼容性。其开源版本提供企业级数据库解决方案,支持MySQL、PostgreSQL和Oracle语法,适用于高并发OLTP、核心业务系统等场景。PolarDB通过开放治理与开发者工具构建完整生态,并展望更丰富的插件功能与AI集成,为中国云原生数据库技术发展贡献重要力量。
628 17
|
8月前
|
存储 关系型数据库 分布式数据库
登顶TPC-C|云原生数据库PolarDB技术揭秘:高可用-无感切换篇
阿里云PolarDB云原生数据库在TPC-C基准测试中以20.55亿tpmC的成绩刷新世界纪录,单位成本仅0.8元人民币。PolarDB通过VotingDisk实现秒级故障切换,RPO=0,提供高可用性。PolarDB还推出国产轻量版,兼具高性能与低成本,满足多样化需求。
|
10月前
|
人工智能 关系型数据库 分布式数据库
100%兼容MySQL!手把手教你基于PolarDB搭建RAG系统
100%兼容MySQL!手把手教你基于PolarDB搭建RAG系统
608 0

相关产品

  • 云原生数据库 PolarDB
  • 推荐镜像

    更多