问题描述:

添加函数后升级脚本与直装的描述不一致导致出现以下状况

可以看到有一些参数或者调用的sql语言不一致的问题

这个时候如果导出元数据地图进行验证,则可以看到报告中指出oid7018和5258这两个函数有hash值不一致的报错

PS:导出数据数据地图对比报告的方法为:

【操作步骤】(请填写详细的操作步骤):

  1. 直接安装一个7.0.0-RC1数据库 gs_upgradechk export -p xxxx 导出元数据校验地图

  2. 安装低版本数据库6.0.0,升级到7.0.0-RC1后 gs_upgradechk verify -p xxxx -v xxx 校验元数据
    -v指定步骤1中导出的元数据地图路径

  3. 分析元数据校验报告,获悉元数据不一致问题

 首先要做的就是将两种情况的元数据地图导出来,复现问题

 ps:必须在可以连接到gitee的环境下执行以下操作,因为升级回滚需要验证版本信息,若没有网络则不能获取到版本hash值导致无法升级

1.安装一个7.0-RC1的数据库gs_upgradechk export -p XXXX 导出元数据校验地图(直装)

要安装那就要先打包编译,先将源码git下来

 进入源码内执行opengauss集成的编译脚本build.sh

sh -x build.sh -m release -3rd /opt/software/binarylibs -pkg

打包好的安装包在output中

opengauss安装和升级需要opengauss官方的运维工具opengauss-OM,所以我们还要打包编译opengauss-OM工具,具体可以参考正确编译openGauss&CM&OM | openGauss社区

 将OM和opengauss源码打包好的安装包放到一个目录(gaussdb_upgrade)中

 解压OM工具

tar -zxvf openGauss-OM-7.0.0-RC1-openEuler20.03-aarch64.tar.gz 

解压以后目录下会出现一个version.cfg,该文件主要指定opengauss的版本,om中默认的版本与我们编译好的99%的概率是不一样的,所以我们要将这个文件的内容改为和我们一样的否则 会因为om工具与opengauss版本不一致导致无法顺利安装或升级

那么我们下一步就是要获取编译好的opengauss的版本信息

version.cfg在上图所指的文件中,可以cp到别的地方解压然后再将其中的版本信息复制过来

新建一个文件夹var,将上面这个tar.bz2放入

打开version.cfg并复制粘贴到gaussdb_upgrade这个文件中

然后就可以顺利安装(PS:安装请参考获取安装包 | openGauss文档 | openGauss社区 这里我因为篇幅原因不过多演示)

安装好以后可以看到安装的版本信息与我们之前复制的版本信息一致。

导出元数据地图,在omm用户下任意目录执行以下命令

gs_upgradechk export -p XXXX

端口号因人而异,我这里是15400

 将这个文件单独保存起来,因为后面要升级,所以需要卸载当前的opengauss,这会将当前的元数据地图一起卸载

2.安装一个6.0-RC1的数据库升级后gs_upgradechk export -p XXXX 导出元数据校验地图(升级)

先卸载刚才安装好的opengauss7.0,我们要先安装一个6.0安装步骤与上面一样

卸载要在omm用户任意目录(非安装目录)下执行以下命令

gs_uninstall --delete-data

再安装6.0并升级为编译好的7.0版本

升级回滚可以参考opengauss官网的教程(openGauss升级指南 | openGauss文档 | openGauss社区

导出元数据地图,将其放在和上一个元数据地图同样的位置

可以根据时间戳判断那个是上一个,那个是刚才升级的。

我们把直装的地图cp到下图所指的路径

 然后在omm用户下执行以下命令

gs_upgradechk verify -p 15400 -v /opt/software/log/omm/omm/om/upgrade_checker/results/EXPORT-2024-12-06-11_29_05.vmap 

-p:指定端口

-v:指定直装生成的元数据地图的路径

 最后会生成一个markdown文件

将这个md文件拖出到windows操作系统下打开搜并搜索7018

这里我们已经能看到上述两个不一致的地方,并且可以看到他是用hash值进行比较,可这个hash是怎么算出来的这是我们需要考虑的东西。

上面我提到了,这个对比生成的markdown就是用直装与升级两种元数据地图进行对比。那么我们就可以打开其中一个元数据地图进行观察,通过观察基本上可以确认这些都是sql和其查询结果。

 那我们可以搜一下都5258和7018这两个关键词

 经过搜索找到了5258,刚好我们可以发现这个5258后面就跟着一个hash值,与之前markdown对比可知这就是计算机在对比的内容

现在又有一个新的问题出现,这个hash值是怎么算出来的?

刚才我们提到,这个元数据地图是sql和其结果,那我们翻上去看看他的sql是什么样的

 于是我们找到了这里,可以看到他是用后面指定的所有字段连接起来,然后用md5()这个函数计算出每个oid对应的hash值,这下一切都清楚了,我们要保证的就是让他被md5包起来的所有字段保持一致就可以。

那么我们需要去哪里修改文件让升级和直装的元数据保持一致?既然是两个hash要求保持一致,那么我们可以大致猜到他应该要我修改两处地方。通过我这边导师告诉我,直装的函数元数据是在builtin_funcs.ini文件中,其存放路径在 opengauss/src/common/backend/catalog/builtin_funcs.ini

而升级脚本在opengauss/src/include/catalog/upgrade_sql/upgrade_catalog_otherdb,

opengauss/src/include/catalog/upgrade_sql/upgrade_catalog_maindb这两个路径下。

这个升级脚本的main和other AI是如下解释的

在你提供的目录结构中,“首个数据库”(upgrade_catalog_maindb/)和“其它数据库系统”(upgrade_catalog_otherdb/)并不直接对应于主从(Master-Slave)关系的概念。这里的“main”和“other”主要指的是不同类型的数据库实例,特别是在升级或变更管理的上下文中。

首个数据库 (Main Database)
定义:这里的“首个数据库”特指那些用于存储核心或系统级信息的数据库,通常是指默认创建的第一个数据库实例,如PostgreSQL中的postgres数据库。它并不是指主数据库(Master Database)。
作用:对于系统级别的变更或升级操作,需要首先在这个数据库上执行,以确保整个系统的稳定性和一致性。
其它数据库系统 (Other Databases)
定义:这里提到的“其它数据库系统”不是指其他类型的数据库管理系统(例如MySQL、Oracle等),而是指在同一DBMS内除了“首个数据库”之外的其他数据库实例。
作用:这些数据库可能被用来存储应用程序数据或其他非系统级别的信息。它们也需要进行相应的变更或升级,但这些操作通常是在“首个数据库”的变更之后进行。

接下来我们先查看builtin_funcs.ini文件并搜索5258

builtin_funs.ini 文件中,通常会列出一系列的内置函数及其相关属性。这些信息对于数据库系统的内部工作非常重要,因为它们定义了系统自带的函数,包括但不限于:

  • 函数名称
  • 函数返回类型
  • 参数类型
  • 函数实现的位置(通常是某个共享库中的符号)
  • 函数的行为标志(如是否严格、是否为聚合函数等)

这个文件的作用是帮助构建系统生成必要的元数据,使得这些内置函数可以在数据库初始化时被正确加载和注册。因此,当你编译和构建 OpenGauss 数据库时,builtin_funs.ini 文件中的配置会被解析并用于设置内部函数表,从而确保用户可以在 SQL 查询中调用这些函数。

 

可以看到有很多to_number函数相关的参数。这些参数具体的意思可以参考(openGauss系统函数添加指导-CSDN博客

我们一般以builtin_funs.ini为基准,通过修改升级脚本将升级后的参数指定为与直装的一致

就以上面的7018的例子举例:

直装:

 升级脚本中的函数实现:

在这里我们发现其实并不好对比哪里有差异,因为升级脚本中有些参数在builtin_funs.ini中是按照参数指定的,有些参数是不写而采用默认值的,所以我们最直观的对比方法就是将上面提到的md5()函数所需的所有字段打印出来。

因为我们现在是升级版本,所以就先将升级版本的元数据打印出来

这里我用到的是下方的命令,在opengauss中copy命令可以将查询结果指定路径保存为指定文件类型,我就直接保存为了csv文件,这样可以直接导出在excel中对比

\copy (SELECT oid,(proname::text) , (pronamespace::text) , (proowner::text) , (prolang::text) , (procost::text) , (prorows::text) ,(provariadic::text) , (protransform::text) , (proisagg::text) , (proiswindow::text) , (prosecdef::text) ,(proleakproof::text) , (proisstrict::text) , (proretset::text) , (provolatile::text) , (pronargs::text) ,(pronargdefaults::text) , (prorettype::text) , (proargtypes::text) , (proallargtypes::text) , (proargmodes::text) ,(proargnames::text) , (prosrc::text) , (probin::text) , (proconfig::text) , (prodefaultargpos::text) ,(fencedmode::text) , (proshippable::text) , (propackage::text) , (prokind::text) , (proargsrc::text) ,(propackageid::text) , (proisprivate::text) , (proargtypesext::text) , (prodefaultargposext::text) ,(allargtypes::text) , (allargtypesext::text) , (oid::text) FROM pg_catalog.pg_proc WHERE oid in (5258,7018)) TO '/home/omm/upgrade.csv' WITH CSV HEADER;

执行完此命令后可以在/home/omm路径下找到upgrade.csv

同样的方法,将直装的sql结果也查询并导出

然后用excel打开并对比

1).新建一个compare.xlsx文件用来对比两个输出内容,分别将install.csv和upgrade.csv复制到compare中

经过对比可以清晰看到7018中的差异

 

可以看到这几处有不同,我们可以根据openGauss系统函数添加指导-CSDN博客此博客中的资料将升级脚本中的参数改为与builtin_funs.ini一致,如果升级脚本实在无法指定或者修改某些参数,那么就将builtin_funs.ini中的参数改为默认值。

PS:这里特别提醒,因为hash值是采用字符串连接在一起进行比较,所以要特别注意特殊字符,比如空格,回车之类的使用,可以用Notepad++进行查看比较

最后我改完后的builtin_funs.ini和脚本如下图所示:

 然后再次编译打包,先直装导出地图和相关数据,再卸载安装6.0.0升级为7.0.0导出对比报告

再次搜索7018,已经无法再搜到相关的错误了

至此,新增函数导致的直装和源数据不一致的问题已经被修复

最后再次提醒

一定要注意特殊字符是否一致

本篇帖子参考多篇文章:

正确编译openGauss&CM&OM | openGauss社区

获取安装包 | openGauss文档 | openGauss社区

openGauss升级指南 | openGauss文档 | openGauss社区

openGauss系统函数添加指导-CSDN博客

以上作者,在此鸣谢

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐