国产数据库OpenGauss的安装部署以及问题排查解决(含源码分析)

💖点赞超100,将取消VIP文章,免费公开

前面都是一些排除得方式,如果想知道最终的问题,可以直接切换到3.3章节

💖如果您需要这篇文章可以扫描下方的公众号二维码,私信回复:opengauss,我们将帮您解答

关键词:Could not create file “global/pg_dw_meta”: Invalid argument
gs_initdb初始化报错:PANIC: Could not create file “global/pg_dw_meta”: Invalid argument 和 gs_ctl 启动报错:gaussDB state is Coredump
在这里插入图片描述

🥰微信公众号:【给点知识】分享小知识,快速成长,欢迎关注呀!(底部点击二维码)
🥰学习宗旨:活到老,学到老。
😍写作宗旨:致力于改变现有文章难读难懂问题。
💖文章作者:给点知识
在这里插入图片描述

0.简介

遇到了这两个错误,由于开源社区没有解决,然后用了docker镜像意外解决了(后面会提到,因为docker目录更换的问题才解决的,不然的话,还是没有办法解决,因为根本问题没有找到)后面官方也关闭了issue,后面找到根因后,无法跟评论了,所以这里就撰写记录以下。目前是全网唯一一个解决的

gs_initdb初始化报错:PANIC: Could not create file "global/pg_dw_meta": Invalid argument 
gs_ctl 启动报错:gaussDB state is Coredump

在开源社区提到这个问题:
https://gitee.com/opengauss/openGauss-server/issues/I97YUE

1.环境介绍

操作系统:CentOS7.4

架构:x86

root>uname -a
Linux localhost 4.4.131.kylin.x86 #1 SMP Wed Jan 24 11:50:07 CST 2024 x86_64 GNU/Linux

openGauss下载地址:https://opengauss.org/zh/download/

openGauss安装包:openGauss-Lite-5.0.1-CentOS-x86_64.tar.gz

在这里插入图片描述

2.安装步骤

这里的安装方式不唯一,其他方式请参考OpenGauss官网

2.1第一步创建用户

因为这里root用户下不允许初始化、安装、启动opengauss所以这里要创建用户

简单介绍下两个命令

  1. useradd:useradd 是一个较为底层的命令,通常在系统管理中使用。它的主要作用是创建用户账户,但不会自动创建用户的家目录、设置默认的登录 shell、添加用户到组等。在使用 useradd 命令时,你需要额外的参数和选项来配置新用户的各种属性。
  2. adduser:adduser 是一个高级命令,它在用户创建过程中提供了更多的交互式选项和默认配置。与 useradd 不同,adduser 会自动创建用户的家目录、设置默认的登录 shell,并允许你在创建用户时选择要加入的组,设置密码等。adduser 命令更加友好和易于使用,适合普通用户创建自己的用户账户。
adduser omm

2.2第二步解压

这里解压到指定得目录:/home/omm/opengauss

tar -jxf openGauss-Lite-5.0.1-CentOS-x86_64.tar.gz -C /home/omm/opengauss

2.2第三步设置环境变量

  1. 修改 vi ~/.bashrc 最后一行增加如下内容

    export GAUSSHOME=/home/omm/opengauss
    export PATH=$GAUSSHOME/bin:$PATH
    export LD_LIBRARY_PATH=$GAUSSHOME/lib:$LD_LIBRARY_PATH
    export GS_CLUSTER_NAME=dbCluster
    ulimit -n 1000000
    
  2. 使配置文件生效

    source ~/.bashrc
    

2.3第四步初始化

使用gs_initdb命令:gs_initdb初始化数据库时,会创建数据库目录、生成系统表、创建默认数据库和模板数据库

gs_initdb -w xxx@123456 -D /opt/data/openbin/openbin/data/single_node --nodename "sgnode" --locale="en_US.UTF-8"

-w:数据库密码
-D:指定数据目录的位置
--nodename:初始化的节点名称。
--locale:为新数据库设置缺省的区域。可以用locale -a查看可用的区域,如zh_CN.gbk等。如果不希望指定特定的区域,则可以用C。

更多信息参考:https://docs-opengauss.osinfra.cn/zh/docs/latest/docs/ToolandCommandReference/gs_initdb.html

初始化正常的情况:表示初始化成功了

在这里插入图片描述

防盗声明:看到这里您别生气我插入文章作者信息,因为有其他非法网站盗用,感谢您的理解
尊重创新,保护知识产权,共创辉煌未来!

如果你在非微信公众号【给点知识】或CSDN发现这篇文章,均为未授权发布,请你点击举报,我们将万分感激
🥰微信公众号:【给点知识】分享小知识,快速成长,欢迎关注呀!(底部点击二维码)
🥰学习宗旨:活到老,学到老。
😍写作宗旨:致力于改变现有文章难读难懂问题。
💖文章作者:给点知识
在这里插入图片描述

2.4第五步启动数据库

gs_ctl是openGauss提供的数据库服务控制工具,可以用来启停数据库服务和查询数据库状态。主要供openGauss管理模块调用。

参数介绍参考:https://docs-opengauss.osinfra.cn/zh/docs/latest/docs/ToolandCommandReference/gs_ctl.html

gs_ctl start -D /opt/data/openbin/openbin/data/single_node -Z single_node -l /home/open/opengauss/logs/server.logs

启动成功截图:

在这里插入图片描述

以上是部署成功的,其实在这个过程中遇到了好多问题。请接着向下看

3.深坑问题

这里主要讲解第一个初始化报错的问题:Could not create file “global/pg_dw_meta”: Invalid argument
因为第二个问题是我在其他可以安装的平台拿到初始化成功后的数据然后再进行启动的时候报的错,所以这里不再说这个问题,因为也是因为第一步导致的
gaussDB state is Coredump

3.1问题发现

在以上步骤按部就班执行之前,出现过这样一个问题,就是在 2.3第四步初始化时报了以下错误

creating directory /home/omm/opengauss_v501/data/single_node ... ok
creating subdirectories ... in ordinary occasionok
creating configuration files ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 1024MB
Begin init undo subsystem meta.
[INIT UNDO] Init undo subsystem meta successfully.
creating template1 database in /home/omm/opengauss_v501/data/single_node/base/1 ... 2024-04-09 22:23:25.268 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [BACKEND] LOG:  InitNuma numaNodeNum: 1 numa_distribute_mode: none inheritThreadPool: 0.
2024-04-09 22:23:25.268 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [BACKEND] LOG:  reserved memory for backend threads is: 220 MB
2024-04-09 22:23:25.268 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [BACKEND] LOG:  reserved memory for WAL buffers is: 128 MB
2024-04-09 22:23:25.268 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [BACKEND] LOG:  Set max backend reserve memory is: 348 MB, max dynamic memory is: 8142 MB
2024-04-09 22:23:25.268 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [BACKEND] LOG:  shared memory 3285 Mbytes, memory context 8490 Mbytes, max process memory 12288 Mbytes
2024-04-09 22:23:25.309 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [CACHE] LOG:  set data cache  size(402653184)
2024-04-09 22:23:25.356 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [SEGMENT_PAGE] LOG:  Segment-page constants: DF_MAP_SIZE: 8156, DF_MAP_BIT_CNT: 65248, DF_MAP_GROUP_EXTENTS: 4175872, IPBLOCK_SIZE: 8168, EXTENTS_PER_IPBLOCK: 1021, IPBLOCK_GROUP_SIZE: 4090, BMT_HEADER_LEVEL0_TOTAL_PAGES: 8323072, BktMapEntryNumberPerBlock: 2038, BktMapBlockNumber: 25, BktBitMaxMapCnt: 512
2024-04-09 22:23:25.366 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [BACKEND] WARNING:  macAddr is 8398/712441605, sysidentifier is 550382198/4278574237, randomNum is 1910168733
2024-04-09 22:23:25.380 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [DBL_WRT] LOG:  dw_bootstrap run start
2024-04-09 22:23:25.396 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [DBL_WRT] PANIC:  Could not create file "global/pg_dw_meta": Invalid argument
2024-04-09 22:23:25.396 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [DBL_WRT] BACKTRACELOG:  tid[26343]'s backtrace:
        /home/omm/opengauss/bin/gaussdb(+0xe0c84e) [0x557fd055984e]
        /home/omm/opengauss/bin/gaussdb(_Z9errfinishiz+0x411) [0x557fd0551a81]
        /home/omm/opengauss/bin/gaussdb(_Z14dw_create_filePKc+0xf3) [0x557fd0f36503]
        /home/omm/opengauss/bin/gaussdb(_Z21dw_generate_meta_fileP21st_dw_batch_meta_file+0x5e) [0x557fd0f3656e]
        /home/omm/opengauss/bin/gaussdb(_Z12dw_bootstrapv+0x82) [0x557fd0f369e2]
        /home/omm/opengauss/bin/gaussdb(_Z13BootStrapXLOGv+0xb51) [0x557fd0f64231]
        /home/omm/opengauss/bin/gaussdb(_Z20BootStrapProcessMainiPPc+0x607) [0x557fd0640df7]
        /home/omm/opengauss/bin/gaussdb(main+0x7bc) [0x557fd0019d1c]
        /usr/lib/libc.so.6(__libc_start_main+0xe7) [0x7f9b97392b27]
        /home/omm/opengauss/bin/gaussdb(+0x940f57) [0x557fd008df57]
        Use addr2line to get pretty function name and line

could not write to child process: Broken pipe
gs_initdb: removing data directory "/home/omm/opengauss_v501/data/single_node"

为了清晰看,这里我再放个截图
在这里插入图片描述

以下是另外一个机器上安装时遇到的问题,同样的错误

在这里插入图片描述

3.2问题排查过程

  1. 分析日志,通过打印的数据可以判断出是错误提示大概是以下两种情况

在这里插入图片描述

(1)具体错误信息中提到了一个名为 “PANIC” 的错误,这通常表示一个严重的系统故障或错误状态。在这种情况下,“PANIC: Could not create file ‘global/pg_dw_meta’: Invalid argument” 表明系统无法创建指定的文件,并且给出了一个无效的参数。

(2)接下来的 “BACKTRACELOG” 部分提供了一些关于错误发生位置和堆栈跟踪的信息。它列出了一系列函数调用,从 “/home/omm/opengauss/bin/gaussdb” 开始,直到最后的 “/home/omm/opengauss/bin/gaussdb(+0x940f57)”。这些信息通常用于跟踪错误发生的位置和调试问题。最后的 “could not write to child process: Broken pipe” 提示无法向子进程写入数据,可能是由于与子进程的通信管道(pipe)断开导致的。

  1. 排查过程,可以看:https://gitee.com/opengauss/openGauss-server/issues/I97YUE

    1. 刚开始以为是权限问题,然后给目录设置了最高权限777 也是不行

    2. 然后以为是libc.so.6版本的问题,看了对应的软连接发现确实和官网发布的版本不一样,于是开始整理版本的问题,最后经过调整到版本一样了,也是不得行。如下是堆栈调试的信息 在这里插入图片描述

  2. 后面通过docker部署第三方提供的enmotech/opengauss 发现也是不行

  3. 于是使用官方提供的opengauss/opengauss可以了:

    == 这里其实有个细节==,是因为当时docker的数据目录在根目录,
    由于官方提供的镜像太大,于是乎我给数据目录改了该到了其他目录。
    

    在这里插入图片描述

3.3“真凶”浮出水面

在这里插入图片描述

  1. 聚焦日志

根据以上提供的方案,发现版本也没有问题,然后目录也赋予了权限,权限也是没啥问题,但是就是报错。后面着重于排查具体的报错内容,于是目光投向这句日志信息

2024-04-09 22:23:25.396 [unknown] [unknown] localhost 140306221617472 0[0:0#0]  [DBL_WRT] PANIC:  Could not create file "global/pg_dw_meta": Invalid argument
  1. 查看源码

(1)Invalid argument 这个说明推测是要么没有权限,要么就是方法传参有问题。于是准备看源码,通过关键词(Could not create file “global/pg_dw_meta”: Invalid argument)定位到源码位置

在这里插入图片描述

(2)这里我把源码主要的内容拿出来,提取关键信息,可以定位到具体报错的代码是open这个函数

在这里插入图片描述

(3)根据以上图片可以看到是open函数的问题,继续抽离出来

fd = open(file_name, (DW_FILE_FLAG | O_CREAT), DW_FILE_PERM);

(4)把常量DW_FILE_FLAG替换,得出如下结果:

fd = open(file_name, (O_RDWR | O_SYNC | O_DIRECT | PG_BINARY | O_CREAT), DW_FILE_PERM);

(5)我们分析下以上这些常量的含义

  • O_CREAT标志:只是一个标识,表示文件不存在就创建,所以跟问题无关。
  • O_RDWR(读写模式):这是标准的读写模式,几乎所有磁盘都支持。通常情况下,这个标志不会导致问题。
  • O_SYNC(同步写入):该标志要求数据写入磁盘后进行同步操作,以确保数据持久化。这个有可能产生影响。
  • O_DIRECT(直接IO):该标志要求数据直接传输到磁盘,绕过操作系统的缓存。这个标志要求磁盘支持直接IO,所以与报错的关联很大
  • PG_BINARY(二进制模式):这个是PG数据库定义的0,与任何值或都不改变原始值,所以排除

根据以上,我们可以看到其中 O_SYNC O_DIRECT 嫌疑比较大,于是我们写个测试脚本

  • 使用c脚本测试输出结果:发现不支持O_DIRECT
    在这里插入图片描述
  • 使用python脚本再次验证:得到根目不支持O_DIRECT
    在这里插入图片描述
    所以以此得到结论:报错原因是因为该磁盘不支持直接IO,没有O_DIRECT这个权限导致的

O_DIRECT(直接IO)这个主要的功能就是,不经过缓存直接通过IO操作读取文件,这里通过这个操作可以减少数据复制和减少内核态和用户态之间的上下文切换次数。

通过使用脚本检测发现,确实根目录不支持,这也证明了在openGauss的代码仓库中提出的issue中说的刚开始使用第三方的镜像不行,但是使用官方提供的就可以,这个是因为由于官方镜像太大,磁盘不足,于是我换了docker的数据目录到/opt/data下了,而恰恰在这个目录是有O_DIRECT权限的,所以部署成功了。

总结以上,给出的解决方案就是:

  1. 给文件系统授予直接IO权限
  2. 把数据目录更改为其他有权限的目录即可。后面我把目录改成其他支持O_DIRECT这个权限的目录就可以部署成功了

彩蛋

1.检测权限脚本

这里写了一个检测所有挂载目录是否有O_DIRECT权限的脚本,奉献给大家使用

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import subprocess

def check_o_direct_support(mount_point):
    try:
        # 创建一个临时文件路径
        temp_file_path = os.path.join(mount_point, "o_direct_test.tmp")
        os.system("touch %s" % temp_file_path)
        # 尝试以 O_DIRECT 标志打开文件
        fd = os.open(temp_file_path, os.O_RDONLY | os.O_DIRECT)
        os.close(fd)
        os.remove(temp_file_path)
        print("{}: 文件系统支持 O_DIRECT".format(mount_point))
    except OSError as e:
        if e.errno == 22:  # EINVAL - Invalid argument
            print("{}: 文件系统不支持 O_DIRECT".format(mount_point))
        elif e.errno == 20:  # ENOTDIR - Not a directory
            print("{}: 不是一个目录,无法创建文件".format(mount_point))
        elif e.errno == 13:  # EACCES - Permission denied
            print("权限不足,无法在 {} 中创建临时文件".format(mount_point))
        else:
            pass
    finally:
        try:
            os.system("rm  %s > /dev/null 2>1&" % temp_file_path)
        except:
            pass

if __name__ == "__main__":
    # 获取系统中的所有挂载点
    df_process = subprocess.Popen(["df", "-P"], stdout=subprocess.PIPE)
    df_output = df_process.communicate()[0]
    mount_points = [line.split()[5] for line in df_output.splitlines()[1:]]

    # 检查每个挂载点的文件系统是否支持 O_DIRECT
    for mount_point in mount_points:
        check_o_direct_support(mount_point)

为者常成,行者常至!你点点赞收藏,就是我最大的动力,如果帮到您请动动小手,如果您有意见,我们评论区见。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐