《PolarDB for PostgreSQL源码与应用实战》——如何参与贡献PolarDB for PostgreSQL开源(中)

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 《PolarDB for PostgreSQL源码与应用实战》——如何参与贡献PolarDB for PostgreSQL开源(中)

《PolarDB for PostgreSQL源码与应用实战》——如何参与贡献PolarDB for PostgreSQL开源(上) https://developer.aliyun.com/article/1232498?spm=a2c6h.13148508.setting.18.5e4f4f0ecmbIFO


开发规范


下面介绍一下开发规范。

大家都知道开发规范对于平时开发工作有重要的作用,但是开发人员平时对开发规范可能关注得不够,但是作为开源项目,开发规范显得尤为重要。


大家都知道这些年PG社区发展非常快,每年都有大版本的发布,他们实际上就是通过一些标准的开发规范,包括一些制度,然后能联合全世界各个国家无数优秀的开发人员,使其协同开发出高质量的代码。所以开发规范在开源项目中就好比一套标准,只要大家做出来的东西符合这套标准,就有了共同沟通的语言,它是一个开源项目能否良好持续发展的关键之一,我们的PolarDB-for-PostgreSQL依然坚持这套标准。


下面将简单介绍一下经常使用的一些规范,希望这些规范能帮助大家在开发过程中更得心应手,提升开发的代码质量,更加符合国际规范,为自己以后的发展提供一个好的支撑。


(一)编码习惯—C语言格式规定

image.png


由于我们的代码大部分都是用C语言开发,因此这里主要介绍一些C语言的开发规范。首先是缩进,可能大家在过去的开发过程中被告知不要使用这种制表服务,就是我们Tab键。实际上PG要求使用tab键,而且是用4列制表符,大家使用时要遵循这个标准,因为所有的代码都是基于这个标准做的。布局规则,比如大括号的位置信息怎么放置,它要遵循BSD习惯,特别是一些if、while、switch等受控块的花括号,受控块的花括号要独自占一行。还有是限制行长度,比如每行的长度建议在80列宽度上,这个是为了代码的可读性,如果代码写得太长,可能不利于代码的阅读。那是否就不能超过80列?也不是,比如说我们的一些errormsg可能会写得很长,如果为了80列的宽度限制而在任意位置进行切断,就会影响可读性,所以目的还是为了可读性。在保证最大可读性的情况下,我们要尽量保证80列的宽度限制。


除此之外,不要使用C++的一些注释风格,比如说双斜杠,还有C编译器,实际上是不接受这种注释的。出于相同的原因,我们也不推荐使用C++的扩展,比如在一个控制块中的一些变量的声明,比如说for语句,for语句如果在控制块里边,声明一个变量I,在这里边是不允许的,需要把这个声明变量拿到for控制框外面的。然后要follow一下注释的模式,通过这种多行注释块去填注释。


(二)编码习惯—如何报错


下面主要讲一下我们的报错信息。


image.png


作为开发人员,知道输出日志信息是我们和软件用户之间一个重要的交流手段,输出的正确日志信息尤其重要,为什么呢?因为它告诉客户我们是否专业,如果写的信息很随意的,客户看到这个软件注册信息的时候,不论你是否写了一个非常优秀的算法或功能,从用户的角度来看,他都会认为这个软件产品不够专业。因此,往往我们忽略的东西可能非常关键。产品里报错信息主要通过两个函数来实现的,分别是ereport和elog。首先讲一下ereport,可以看到ereport这个语句主要分三部分,error就是我们的严重级别,errcode就是一些错误代码,最后是errmsg。严重级别根据PG里边的一些规范,我们这里规定是用DEBUG5到DEBUG1,包括我们的NOTICED、WARNING、ERROR、FATAL、PANIC,随着级别越来越高,对于客户的信息产生了不同的重要程度,也可以通过我们的配置文件设置给客户输出什么级别的信息。


如果是error或者更高,需要注意的是如果严重级别没有设置,或者说严重级别设置了error或者更高ereport,会终止用户定义函数的执行,并且不会返回到调用者。如果是严重级别低于error,那ereport会正常返回。errcode指定对于该情况的一些错误标识代码,这里的错误代码一般由5个字符组成,这5个字符包含了一些数字和大写字母,它表示多种错误和警告情况的代码,所以它也是分层次的。


前两位一个是错误的总分类,后三个字符表示一个情况的子类,代码5个0,“00000”代表着一个成功的状态,这可以帮助我们快速定位问题的类型,也大概知道debug的方向在哪里。如果没有指定errcode错误严重性,特别是error或者更高的错误标识,会默认使用ERRCODE_INTERNAL_ERROR。如果错误级别是warning标识符的这种,errcode会默认使用ERRCODE_WARNING 。


如果错误严重级别是在notice以及以下,就会使用ERRCODE_SUCCESSFUL_COMPLETION这么一个errcode,这是一个默认的情况,如果没有设置errcode的话。


对于我们来讲,有的时候不用errcode是一个很方便的情况,但是如果考虑不用errcode,要很清楚自己不用的原因是什么,考虑一下它们是否合适。


剩下就是errmsg。errmsg主要是提供消息主体,就是要报错的信息。然后就是ereport,ereport这里边实际上还有很多辅助函数,就里提到了我们的errcode(),errmsg()这里边都是辅助函数,还有很多其他的辅助函数,这些辅助函数大家可以在PG的官网上进行查看。


下面讲第二种错误代码elog。


elog的作用是什么?它是一个旧有的模式,可以等效于ereport模式,可以看到它提供了level,错误级别是一样的,但它没有提供errcode,就跟刚才讲到的,根据严重级别提供默认的errcode。然后消息通过一个辅助函数errmsg_internal()去show出来,过程和刚才讲到的ereport里面的errmsg是不同的,errmsg()根据地域设置设定,比如它可以翻译成对应国家的语言,比如说翻译成汉语,实际上errmsg_internal()这个语言就不会受翻译的限制,它可以自动把原的语言打印出来。


为什么还要保留这种旧有的模式呢?因为它足够简洁,在有一些内部的错误,比如说PG内核一些内部错误的时候,这种错误实际上它并不是给用户show出来的,不是用户感兴趣的错误,可以用这种简洁的模式进行打印,非常方便,因此也得到了保留。


(三)编码习惯—错误消息如何撰写

image.png


下面我们讲讲消息怎么输出,这也是很关键的一个步骤。


错误消息通常分成三部分,主要的错误消息是简单概要的介绍一下这是什么错误,如果这个简单概要的信息不够完整,或者不能够足够表达出具体的错误,也可以通过添加Detail信息,把具体的细节打印出来。

同时,如果你提供了比如对错误的一些修复建议,可以通过这种Hint的方式进行加入,比如可以提供一下这个东西是不是文件不见了,可以去做一些文件添加等提示信息。


然后就是引号,因为在引用时,英文文本都应该使用双引号,我们通常用这个引号界定文件名,包括用户提供的一些标识服务,以及其他可能包含词的变量,不要用他们标记那些不包含词的变量。为什么要这么做?实际上因为我们有一些对象插入到信息中是会产生歧义的,如果不用双引号,那就产生了歧义,把它插到消息中,通过双引号可以避免歧义。


还有就是语法和标点类主要错误信息,例如通常第一个字母不要大写,不要用一个句点结束一个消息,甚至不要考虑用一个感叹号结束一个消息。


关于详细和提示信息,尽量要使用完整的句子,并且每一句都要用句点结束,对句子的第一个词进行首字母大写,如果后面跟着另一个句子,在句号后面放两个空格。


为什么有这些具体的建议或规范,比如主要消息为什么不要大写?第一个字母怎么不要大写?因为这些消息对于用户来讲,他会把你的信息很方便插入到各种各样语法的上下文中,如果用完整句子可能就不方便。因为通常来讲,主要消息通常不是一个语法上完整的句子,如果它是一个很长的句子,尽量把它拆分成一个主要部分和一个详细部分。不过详细和提示消息会很长,通常需要包括多个句子,为了一致,即使它们只是一个句子,也应该遵循完整句子的风格,我们要求它的首字母大写,每个句都句点结束。

image.png


关于大写和小写方面,对消息使用小写的这种形式,主要错误消息里面第一个字母也要小写,如果是SQL命令,一些关键词出现在消息中,请为它们使用大写,因为这也是为了明确告诉大家这些信息。然后避免用被动态,尽量使用主动语态,


在有主语时使用完整的句子,比如说类似于“A could not do B”,如果主语是程序本身,请使用没有主语的电报风格,但不要为程序加上“I”。因为程序并不是人,所以不需要去假装。


现在时和过去时,如果一次尝试做某事失败,但是可能下一次就成功了,就使用过去式,如果失败必定是持久的,那就使用现在时。比如下面这两个句“could not open”和“cannot open”有什么区别?第一个表示打开文件尝试失败,该消息应该给出一个具体的原因,比如说磁盘满了或者是文件不存在,过去时更合适,因为下一次磁盘可能就不满了,或者是文件就存在了。第二种形式表示打开所提及文件的功能在程序中根本就不存在,或者概念上是不可能的,现在时更合适,因为在该种情况将无限保持的情况下,这种错误也将无限保持。因为你的功能没有,即使文件存在,也没有这个功能,为什么要这样呈现?普通用户没有能力从消息的时态上得出重要的结论的,但是由于语言给我们提供了语法,就应该正确地使用它。

image.png


关于对象类型,在引用一个对象名称时,说明该对象的类型,因为如果不说明它就没有人会了解这个对象是什么类型,比如 “foo.bar.baz”具体是什么东西,我们需要给它一个具体说明。


然后是组装错误消息。比如有一些消息是在别处生成的,这种产生的文本怎么嵌入到我们消息里面。消息总是要说明为什么错误会发生,如果没有已知的原因,最好去修复这个代码。比如一个错误的实例“could not open file”,这种没有给的原因,没有给原因就不确定错误的信息是怎么产生的。最好的是说比如“could not open file”,然后改给它一个I/O failure,是因为I/O错误导致的。


不要在消息中使用函数名,可能大家开发过程中经常会在日志里用到这个函数名,但是日志写函数名实际上对用户来讲是没有任何作用的,因为他不清楚你在里边实现什么样的,请大家把函数名保留在debug阶段,最后提交的时候还是要把函数名去掉,写成一个合规的错误消息。避免缩略语,比如尽量不要使用“can't”,应该使用“cannot”。避免使用“Unable、Bad、Illegal、Unknown”这种单词,为什么?比如说unable,它更接近于被动态,使用“cannot”等会更好。比如bad  result这种错误信息,实际上很难从错误信息中知道到底是什么东西,最好是写出一个结果不好原因,比如Invalid format,是一个无效的格式。Illegal表示违反法律,最好是写成Invalid,如果说明为什么无效就更好了。尝试避免Unknown,为什么?比如说Unknown responds,如果你不知道响应是什么,怎么知道它是错误的?应该使用Unrecognized,相当于没有识别或这是一个更好的选择。


Find and Exists,找到还是存在的问题。如果是使用了某个算法去查找,而算法执行失败了,就用“无法找到”更好,如果是已知的资源位置,但是程序无法去找到它,那“不存在”会更合适一点。


(四)编码习惯—其他编码习惯

下面介绍一下其他的一些编码习惯。

image.png


比如我们在C语言里一些宏和内联函数,因为带有参数的宏和内联函数在代码中经常会被使用,当使用宏时有多次计算风险的时候,就推荐使用后者,如果是其他情况,只能尽量去使用宏,因为宏使用起来会更容易一点。

信号处理函数是一个很重要的部分,因为除了一些特殊的代码,信号处理函数处理不好会导致程序混乱,在信号处理器中,只应该调用那些对异步信息安全的函数,比如在处理信号的时候去操作一个锁,这个锁是在外部调用的,已经锁上了,此时信号处理函数中要去加这个锁可能会发生什么,大家清楚。在这里推荐只是提示一下这个信号已经到达,并用一个 latch 去唤醒信号处理器之外的一些代码,比如记录一下这是一个sigh up信号,同时去唤醒一些其他代码去执行。

image.png


还有就是调用函数指针,如果函数指针是个简单的变量,调用的时候推荐显式调用,虽然不加也是会有效的。

(五)编码习惯—其他语言编码规范

image.png


如上所示,还有一些其他的开发规范。因为我们不仅有C语言,还有其他的语言,大家自行参考上方地址的信息,参考对应的代码规范。


《PolarDB for PostgreSQL源码与应用实战》——如何参与贡献PolarDB for PostgreSQL开源(下) https://developer.aliyun.com/article/1232495?spm=a2c6h.13148508.setting.20.5e4f4f0ecmbIFO




相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
1月前
|
关系型数据库 Serverless 分布式数据库
【公测】PolarDB PostgreSQL版Serverless功能免费使用​!
【公测】PolarDB PostgreSQL版Serverless功能免费使用​,公测于2024年3月28日开始,持续三个月,公测期间可以免费使用!
|
1月前
|
Docker 容器 关系型数据库
【PolarDB-X从入门到精通】 第四讲:PolarDB分布式版安装部署(源码编译部署)
本期课程将于4月11日19:00开始直播,内容包括源码编译基础知识和实践操作,课程目标是使学员掌握源码编译部署技能,为未来发展奠定基础,期待大家在课程中取得丰富的学习成果!
【PolarDB-X从入门到精通】 第四讲:PolarDB分布式版安装部署(源码编译部署)
|
14小时前
|
关系型数据库 MySQL 分布式数据库
如何将数据从MySQL迁移到PolarDB?
【5月更文挑战第13天】如何将数据从MySQL迁移到PolarDB?
7 0
|
1天前
|
存储 关系型数据库 MySQL
数据管理的艺术:PolarDB开源版详评与实战部署策略(一)
PolarDB-X是阿里巴巴自研的高性能云原生分布式数据库,基于共享存储的Shared-nothing架构,支持MySQL生态,具备金融级高可用、分布式水平扩展、HTAP混合负载等能力。它通过CN(计算节点)和DN(存储节点)实现计算与存储分离,保证数据强一致性,并支持全局二级索引和多主多写。PolarDB-X开源版提供更高程度的定制化和控制权,适合追求技术自主性和成本优化的开发者。部署方式包括RPM包、PXD工具和Kubernetes,其中PXD工具提供了一键部署的便利性。
46711 10
|
4天前
|
关系型数据库 分布式数据库 数据库
开源之夏2024学生报名启动!阿里云PolarDB社区项目期待你的参与!
开源之夏2024学生报名启动!阿里云PolarDB社区带你变得更强!
开源之夏2024学生报名启动!阿里云PolarDB社区项目期待你的参与!
|
4天前
|
关系型数据库 MySQL 分布式数据库
快速体验开源PolarDB -X 部署安装
在CentOS上部署PolarDB-X标准版集群的体验包括三步:安装python3和docker(如果未预装),然后使用venv创建环境,安装pxd并验证。接着,通过`pxd tryout -t standard`部署集群,该过程需拉取大量镜像,可能耗时且占用数GB空间,建议事先清理空间并了解资源需求。部署后,可查询集群状态和健康信息。最终,使用`pxd cleanup`清理。过程中因磁盘空间不足遇到问题,建议体验前提供系统配置需求,并允许用户自定义MySQL参数。
|
4天前
|
存储 关系型数据库 大数据
PolarDB 开源评测
开源PolarDB-X,源自阿里云PolarDB,具备分布式存储和计算能力,以其开源特性、成本效益、社区支持和灵活性受到青睐。支持多种部署模式,适合大规模数据处理。然而,其复杂性与文档不完善可能是挑战,建议优化部署流程以降低使用难度。
|
5天前
|
关系型数据库 Linux 分布式数据库
源码编译实现PolarDB-X部署安装的体验报告
本文档记录了编译安装PolarDB-X的步骤,包括设置CentOS开发环境、从GitHub获取源码、编译(耗时较长)、解决依赖和权限问题、安装部署及测试验证。作者建议优化文档细节、减少编译时间、改进错误提示,并提议提供一键安装依赖脚本、新手视频教程及加强社区支持。整个过程虽有挑战,但具有成就感。
16 0
|
13天前
|
DataWorks 关系型数据库 MySQL
DataWorks产品使用合集之在DataWorks中,如何通过PolarDB for MySQL来查看binlog日志
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
28 1
|
15天前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用合集之PolarDB MySQL标准版中带有分区功能吗
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。

相关产品

  • 云原生数据库 PolarDB