OceanBase 二次开发 之 Kunpeng + openEuler 适配优化(一)

引子

由于时间和精力的原因,上一篇关于OceanBase二次开发的帖子Hello OceanBase!开启OB二次开发之后就很少在社区活动了。当然,还是要感谢社区小编和运营们不失时机的提醒与督促_。这两天在社区里面爬楼梯,翻了翻OB的相关帖子。近期OB社区的主旋律应该是性能相关主题——测试体验和性能调优等方面的。这个主题很好,很复杂,同时涉及的范围也很广,影响性能的因素也很多。我认为,如果把DB比作一辆车,那么车子能跑多快一般取决于三个方面:

  1. 车子的硬件条件,比如发动机的排量
  2. 车子本身的一些设计,比如变速箱的设计,涡轮增压,空气动力学的利用等一些工业设计
  3. 驾驶员本身的驾驶技能与技巧,以及对车子特点的熟悉程度

硬件条件对应数据库运行的基础设施(服务器,操作系统):目前主流的Intel X86,主频可以达到(3.7GHz~4.1GHz)。但是这东西毕竟是进口的发动机不能自主可控,那么对应国产的发动机有海光x86(2.0GHz~2.4GHz),鲲鹏ARM(2.6GHz)等,虽然排量低一点,但是有更多的气缸,比如主流的Kunpeng 920 2座*64 = 128核。在不同的场景下不同的发动机各有优势,这里不做对比。

车子本身的设计对应的就是数据库的设计与架构:包括各种优化器,算子下推,顺序写等等。

驾驶员就是指DBA和数据库使用者:这些直接的数据库用户对数据库的掌握和了解情况,一定程度上也会影响车子的速度。车子到手后是否能发挥最佳的性能,对于DBA这些老司机来说任重而道远。

本文将针对第一点进行探索,先换个底盘(openEuler)和发动机(Kunpeng)看看效果,而第二点是数据库大厂工程师们努力的目标,至于第三点就交给“老司机”吧~

概要

2022-03-30,OceanBase社区release了3.1.3_CE版本。值得注意的是“新增支持ARM平台”功能。我相信这一版本的发布是社区版OceanBase的一个重要里程碑,在信创的大背景下,ARM已成为主要的替代方案。严重点讲,缺失了对ARM的支持,可能会损失一半的市场。如前所述,如果把DB比作汽车,除了性能指标外,市场保有量才是决定是否可以长期稳定立足行业的关键,有了保有量就会有更多的用户反馈,用户反馈又决定了产品的质量,质量提高又会带动销量和保有量,这是一个良性循环的过程,也是目前各大国产数据库厂商努力推广,占领市场的原因吧。

在这里插入图片描述
在这里插入图片描述

目前ARM版支持的编译操作系统只有(alios和centos)两种,但主流的可适配ARM架构的操作系统还有很多,目前的国产操作系统中大部分是基于华为欧拉和阿里龙蜥两大开源社区的商业发行版,知名的包括麒麟Kylin v10,统信UOS(1021a:基于阿里龙蜥内核,1021e:基于华为openEuler内核)。如果使用ARM架构,大部分用户会选择基于openEuler内核的操作系统(针对鲲鹏有优化)。因此,虽然OceanBase 已经release了ARM版本(实测,可以直接运行在鲲鹏+欧拉上),但针对性的优化应该还不够完善,当然这只是时间问题,我相信很快就会有ARM的优化方案和版本推出。

本文将针对ARM版OceanBase迁移到Kunpeng+openEuler进行尝试与实践。目标是,通过源码重新编译3.1.3_CE for ARM,使用华为的毕昇编译器(HUAWEI BiSheng Compiler 2.1.0.B010 clang version 12.0.0 (clang-0749c5924208 flang-d6f2a3bc24a)替代原有的llvm 11.0.1。使用jemalloc替代原有的内存分配器,最终达到性能提升的目的。

写在前面

可能这又是一篇小众的帖子,社区里面的“老司机”们未必能看完。所以先把成果放在这里吧。

  1. 支持在酷跑+欧拉上可编译的源码仓库(fork 于社区版源码仓库):https://github.com/Frank-gh/oceanbase
    在这里插入图片描述

注意:切换至openEuler 分支

  1. 使用方式
git clone https://github.com/Frank-gh/oceanbase.git
cd oceanbase
git checkout openEuler
sh build release --init --make
  1. 该仓库将持续维护,期待各位的测试结果和问题反馈。

总体目标

  • OceanBase源码可以在,鲲鹏 920 + openEuler系统上编译;
  • 替换通用的LLVM,CLANG,使用针对Kunpeng优化的毕昇编译器(基于clangv12.0.0);——后续会针对编译器升级进行性能测试
  • 增加鲲鹏优化的编译选项,并使用jemalloc替换自带的内存分配器;——后续会针对调整进行新能测试对比
  • 最终希望能得到一个在鲲鹏+欧拉上的定制优化版本,并提供给社区用户进行测试体验。

一、环境准备

使用华为的ECS,本次实践只为了编译,所以配置要求不高,但编译比较吃CPU和内存,太小的话会出现OOM的情况,建议比以下配置使用更多的CPU和内存(推荐:16c,32G)

CPU架构操作系统cpu(s)内存硬盘
Kunpeng-920 2.4GHz (ARM)openEuler 20.03 (LTS)816G40G

操作系统信息

[root@ecs-613f ~]# cat /etc/os-release
NAME="openEuler"
VERSION="20.03 (LTS)"
ID="openEuler"
VERSION_ID="20.03"
PRETTY_NAME="openEuler 20.03 (LTS)"
ANSI_COLOR="0;31"

二、编译准备

2.1 获取源码

git clone https://github.com/Frank-gh/oceanbase.git
cd oceanbase
## 切换到 3.1.3_CE tag
git checkout 3.1.3_CE
## 创建新的分支 
git checkout -b openEuler

2.2 安装依赖

理想情况下,OceanBase所有的依赖会在编译前都自动下载deps/3rd/pkg目录并安装到deps/3rd/usr/local/oceanbase/depsdeps/3rd/usr/local/oceanbase/devtools下面,但实际操作,虽然在devtools下已安装,但是编译的时候并未cover全部。因此需要安装如下包,主要是语法解析和词法解析(lex,yacc)的包。

yum install flex bison bison-devel

另外一个可以选择安装,如果不安装可以设置环境变量来解决:

export LD_LIBRARY_PATH=$SCR_DIR/deps/3rd/usr/local/oceanbase/devtools/lib64:$LD_LIBRARY_PATH

或者直接安装

yum install libatomic

三、调试编译脚本

3.1 首次编译

[root@ecs-613f oceanbase]# ./build.sh release --init --make
[ERROR] 'openEuler 20.03 (LTS) (aarch64)' is not supported yet.

**调试:**使用 -x 调试build.sh脚本sh -x build.sh release --init --make

+ do_init
+ cd /root/oceanbase/deps/3rd
+ bash dep_create.sh
[ERROR] 'openEuler 20.03 (LTS) (aarch64)' is not supported yet.
+ exit 1

发现在执行 dep_create.sh 脚本时报错,继续跟踪…

**调试:**使用 -x 调试dep_create.sh脚本 bash -x dep_create.sh

[root@ecs-613f 3rd]# cd /root/oceanbase/deps/3rd
[root@ecs-613f 3rd]# bash -x dep_create.sh

+ get_os_release
+ [[ aarch64x == \x\8\6\_\6\4\x ]]
+ [[ aarch64x == \a\a\r\c\h\6\4\x ]]
+ case "$ID" in
+ not_supported
+ echo '[ERROR] '\''openEuler 20.03 (LTS) (aarch64)'\'' is not supported yet.'
[ERROR] 'openEuler 20.03 (LTS) (aarch64)' is not supported yet.
+ return 1
+ exit 1

**is not supported yet ** ,好吧,开始撸脚本。

可以看到下面的脚本中支持aach64上编译的操作系统目前只有alios和centos。

function get_os_release() {
  if [[ "${OS_ARCH}x" == "x86_64x" ]]; then
    case "$ID" in
      alinux)
        version_ge "2.1903" && compat_centos7 && return
        ;;
      alios)
        version_ge "8.0" && compat_centos8 && return
        version_ge "7.2" && compat_centos7 && return
        ;;
      anolis)
        version_ge "8.0" && compat_centos8 && return
        version_ge "7.0" && compat_centos7 && return
        ;;
      ubuntu)
        version_ge "16.04" && compat_centos7 && return
        ;;
      centos)
        version_ge "8.0" && OS_RELEASE=8 && return
        version_ge "7.0" && OS_RELEASE=7 && return
        ;;
      debian)
        version_ge "9" && compat_centos7 && return
        ;;
      fedora)
        version_ge "33" && compat_centos7 && return
        ;;
      opensuse-leap)
        version_ge "15" && compat_centos7 && return
        ;;
      #suse
      sles)
        version_ge "15" && compat_centos7 && return
        ;;
      uos)
        version_ge "20" && compat_centos7 && return
        ;;
    esac
  elif [[ "${OS_ARCH}x" == "aarch64x" ]]; then
    case "$ID" in
      alios)
        version_ge "8.0" && compat_centos8 && return
        version_ge "7.0" && compat_centos7 && return
        ;;
      centos)
        version_ge "8.0" && OS_RELEASE=8 && return
        version_ge "7.0" && OS_RELEASE=7 && return
        ;;
    esac
  fi

脚本中获取操作系统版本信息的逻辑

[root@ecs-613f ~]# source /etc/os-release
[root@ecs-613f ~]# PNAME=${PRETTY_NAME:-"${NAME} ${VERSION}"}
[root@ecs-613f ~]# echo $PNAME
openEuler 20.03 (LTS)
[root@ecs-613f ~]# OS_ARCH="$(uname -m)"
[root@ecs-613f ~]# PNAME="${PNAME} (${OS_ARCH})"
[root@ecs-613f ~]# echo $PNAME
openEuler 20.03 (LTS) (aarch64)

修改脚本,增加openEuler的分支,同时,依赖包列表会在同级目录下找到 oceanbase.el8.aarch64.deps ,当然也可以新建一个Euler的deps,这里就不做了,后续再完善。

  elif [[ "${OS_ARCH}x" == "aarch64x" ]]; then
    case "$ID" in
      alios)
        version_ge "8.0" && compat_centos8 && return
        version_ge "7.0" && compat_centos7 && return
        ;;
      centos)
        version_ge "8.0" && OS_RELEASE=8 && return
        version_ge "7.0" && OS_RELEASE=7 && return
        ;;
      # add for openEuler by Shylock
      openEuler)
        version_ge "20.03" && OS_RELEASE=8 && return
        ;;
    esac

oceanbase.el8.aarch64.deps内容如下:(dep_create.sh通过配置中的repo下载对应的rpm包,并安装的指定目录)

os=8
arch=aarch64
repo=http://mirrors.aliyun.com/oceanbase/development-kit/el/8/aarch64/

[deps]
devdeps-gtest-1.8.0-16.el8.aarch64.rpm
devdeps-isa-l-static-2.22.0-17.el8.aarch64.rpm
devdeps-libcurl-static-7.29.0-16.el8.aarch64.rpm
devdeps-libunwind-static-1.6.2-12.el8.aarch64.rpm
devdeps-mariadb-connector-c-3.1.12-16.el8.aarch64.rpm
devdeps-openssl-static-1.0.1e-12.el8.aarch64.rpm
devdeps-libaio-0.3.112-6.el8.aarch64.rpm
devdeps-rapidjson-1.1.0-3.el8.aarch64.rpm

[tools]
obdevtools-binutils-2.30-7.el8.aarch64.rpm
obdevtools-bison-2.4.1-9.el8.aarch64.rpm
obdevtools-ccache-3.7.12-6.el8.aarch64.rpm
obdevtools-cmake-3.20.2-15.el8.aarch64.rpm
obdevtools-flex-2.5.35-10.el8.aarch64.rpm
obdevtools-gcc-5.2.0-15.el8.aarch64.rpm
obdevtools-llvm-11.0.1-40.el8.aarch64.rpm

[tools-deps]
devdeps-rocksdb-6.22.1-26.el8.aarch64.rpm

至此,基本的修改已经完成,可以再编译试试。

3.2 再次编译

回到源码根目录,重新编译。

[root@ecs-613f oceanbase]# ./build.sh release --init --make

如果顺利,再次编译会直接成功,成功后查看生成的observer。

[root@ecs-613f observer]# file  observer
observer: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[md5/uuid]=b936eff9babeed59708f2e5ccdd12518, with debug_info, not stripped

[root@ecs-613f observer]# ldd observer
        linux-vdso.so.1 (0x0000fffd9e060000)
        libm.so.6 => /lib64/libm.so.6 (0x0000fffd9df80000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x0000fffd9df40000)
        libdl.so.2 => /lib64/libdl.so.2 (0x0000fffd9df10000)
        librt.so.1 => /lib64/librt.so.1 (0x0000fffd9dee0000)
        libatomic.so.1 => /root/oceanbase/deps/3rd/usr/local/oceanbase/devtools/lib64/libatomic.so.1 (0x0000fffd9deb0000)
        libc.so.6 => /lib64/libc.so.6 (0x0000fffd9dd20000)
        /lib/ld-linux-aarch64.so.1 (0x0000fffd9e070000)

查看pkg目录,可以看到已经下载的rpm包:

[root@ecs-613f 3rd]# tree pkg/
pkg/
├── devdeps-gtest-1.8.0-16.el8.aarch64.rpm
├── devdeps-isa-l-static-2.22.0-17.el8.aarch64.rpm
├── devdeps-libaio-0.3.112-6.el8.aarch64.rpm
├── devdeps-libcurl-static-7.29.0-16.el8.aarch64.rpm
├── devdeps-libunwind-static-1.6.2-12.el8.aarch64.rpm
├── devdeps-mariadb-connector-c-3.1.12-16.el8.aarch64.rpm
├── devdeps-openssl-static-1.0.1e-12.el8.aarch64.rpm
├── devdeps-rapidjson-1.1.0-3.el8.aarch64.rpm
├── devdeps-rocksdb-6.22.1-26.el8.aarch64.rpm
├── obdevtools-binutils-2.30-7.el8.aarch64.rpm
├── obdevtools-bison-2.4.1-9.el8.aarch64.rpm
├── obdevtools-ccache-3.7.12-6.el8.aarch64.rpm
├── obdevtools-cmake-3.20.2-15.el8.aarch64.rpm
├── obdevtools-flex-2.5.35-10.el8.aarch64.rpm
├── obdevtools-gcc-5.2.0-15.el8.aarch64.rpm
└── obdevtools-llvm-11.0.1-40.el8.aarch64.rpm

其中obdevtools-llvm-11.0.1-40.el8.aarch64.rpmobdevtools-gcc-5.2.0-15.el8.aarch64.rpm 这两个包实际上是可以考虑进行升级。对应Kunpeng上的定制编译器,分别是BiSheng Compiler 2.1.0(基于clang v12) 和 GCC for openEuler(基于gcc v9.3.0),这两款针对Kunpeng ARM架构都有不同程度的优化,也是本次实践想要得到的结果——即通过编译选项,内存分配器,操作系统参数的优化,是否可以提升OceanBase在鲲鹏 ARM上的性能。

3.3 编译器升级

下载毕昇编译器

wget -c https://mirrors.huaweicloud.com/kunpeng/archive/compiler/bisheng_compiler/bisheng-compiler-2.1.0-aarch64-linux.tar.gz

将tar包放在deps/3rd目录下。

修改dep_create.sh脚本

增加以下几行代码——下载,安装毕昇编译器。
在这里插入图片描述

修改依赖包列表oceanbase.el8.aarch64.deps

在这里插入图片描述

删掉obdevtools-llvm-11.0.1-40.el8.aarch64.rpm这行。

3.4 再来一次

回到源码根目录,重新编译。

[root@ecs-613f oceanbase]# ./build.sh release --init --make

解决编译报错

第三次编译会报错,原因为新的编译器不支持宏嵌套的使用语法。

In file included from /root/oceanbase/build_release/deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/Unity/unity_oblib_rpc_common/1_cxx.cxx:51:
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:14: error: '(' and '{' tokens introducing statement expression appear in different macro expansion contexts [-Werror,-Wcompound-token-split-by-macro]
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:5: note: expanded from macro 'FALSE_IT'
    (stmt);            \
    ^
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:23: note: '{' token is here
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
                      ^
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:6: note: expanded from macro 'FALSE_IT'
    (stmt);            \
     ^~~~
In file included from /root/oceanbase/build_release/deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/Unity/unity_oblib_rpc_common/1_cxx.cxx:51:
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:45: error: '}' and ')' tokens terminating statement expression appear in different macro expansion contexts [-Werror,-Wcompound-token-split-by-macro]
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
                                            ^
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:6: note: expanded from macro 'FALSE_IT'
    (stmt);            \
     ^~~~
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:14: note: ')' token is here
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:10: note: expanded from macro 'FALSE_IT'
    (stmt);            \
         ^
[ 44%] Building CXX object deps/oblib/src/lib/compress/CMakeFiles/oblib_compress.dir/ob_stream_compressor.cpp.o
2 errors generated.
make[2]: *** [deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/build.make:94: deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/Unity/unity_oblib_rpc_common/1_cxx.cxx.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:4083: deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/all] Error 2

解决方案,修改源代码deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp
在这里插入图片描述

去掉语法糖的写法FALSE_IT ,修改后代码风格有点丑,逻辑应该没有问题,后续有时间回归一下单元测试,验证逻辑是否正确。

3.5 再再次编译

回到源码根目录,重新编译。

[root@ecs-613f oceanbase]# ./build.sh release --init --make

查看clang版本

[root@ecs-613f devtools]# /root/oceanbase/deps/3rd/usr/local/oceanbase/devtools/bin/clang -v
HUAWEI BiSheng Compiler 2.1.0.B010 clang version 12.0.0 (clang-0749c5924208 flang-d6f2a3bc24a5)
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /root/oceanbase/deps/3rd/usr/local/oceanbase/devtools/bin
Found candidate GCC installation: /root/oceanbase/deps/3rd/usr/local/oceanbase/devtools/bin/../lib/gcc/aarch64-redhat-linux/5.2.0
Found candidate GCC installation: /usr/lib/gcc/aarch64-linux-gnu/7.3.0
Selected GCC installation: /usr/lib/gcc/aarch64-linux-gnu/7.3.0
Candidate multilib: .;@m64
Selected multilib: .;@m64

编译通过~

四、升级内存分配器

修改cmake/ENV.cmake

在这里插入图片描述

  • -mtune=tsv110 :aarch流水线优化选项
  • -ljemalloc:内存分配器,减少内存碎片

最后一次编译

回到源码根目录,重新编译。

[root@ecs-613f oceanbase]# ./build.sh release --init --make

编译成功~

五、验证

5.1 链接情况验证

在这里插入图片描述

ldd可以看到libjemalloc可以成功链接。

5.2 查看observer编译版本信息

可以看到BUILD_VRANCH: openEuler
在这里插入图片描述

六、FQA

Q1:基础编译OceanBase报错

CMake Error at src/sql/parser/CMakeLists.txt:65 (add_library):
  Cannot find source file:

    sql_parser_mysql_mode_lex.c


CMake Error at src/sql/parser/CMakeLists.txt:65 (add_library):
  No SOURCES given to target: ob_sql_proxy_parser_objects


CMake Error at src/sql/parser/CMakeLists.txt:93 (add_library):
  No SOURCES given to target: ob_sql_server_parser_static


CMake Error at src/sql/parser/CMakeLists.txt:72 (add_library):
  No SOURCES given to target: ob_sql_server_parser_objects


CMake Error at src/sql/parser/CMakeLists.txt:88 (add_library):
  No SOURCES given to target: ob_sql_proxy_parser_static

A1:缺少语法、词法分析的依赖flex,bison

yum install flex bison bison-devel

Q2:更换clang版本后编译报错

In file included from /root/oceanbase/build_release/deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/Unity/unity_oblib_rpc_common/1_cxx.cxx:51:
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:14: error: '(' and '{' tokens introducing statement expression appear in different macro expansion contexts [-Werror,-Wcompound-token-split-by-macro]
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:5: note: expanded from macro 'FALSE_IT'
    (stmt);            \
    ^
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:23: note: '{' token is here
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
                      ^
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:6: note: expanded from macro 'FALSE_IT'
    (stmt);            \
     ^~~~
In file included from /root/oceanbase/build_release/deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/Unity/unity_oblib_rpc_common/1_cxx.cxx:51:
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:45: error: '}' and ')' tokens terminating statement expression appear in different macro expansion contexts [-Werror,-Wcompound-token-split-by-macro]
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
                                            ^
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:6: note: expanded from macro 'FALSE_IT'
    (stmt);            \
     ^~~~
/root/oceanbase/deps/oblib/src/rpc/obrpc/ob_rpc_processor_base.cpp:454:14: note: ')' token is here
  } else if (FALSE_IT({ NG_TRACE(transmit); })) {
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/oceanbase/deps/oblib/src/lib/utility/utility.h:29:10: note: expanded from macro 'FALSE_IT'
    (stmt);            \
         ^
[ 44%] Building CXX object deps/oblib/src/lib/compress/CMakeFiles/oblib_compress.dir/ob_stream_compressor.cpp.o
2 errors generated.
make[2]: *** [deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/build.make:94: deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/Unity/unity_oblib_rpc_common/1_cxx.cxx.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:4083: deps/oblib/src/rpc/CMakeFiles/oblib_rpc.dir/all] Error 2

A2:修改代码逻辑避免宏嵌套
在这里插入图片描述

七、总结

至此,整个迁移工作已经完成,使用时可以通过手工替换完成升级,后续会提供rpm的形式发布。文章逻辑是按照实操过程进行的记录,反复编译了5次,如果大家想节省时间的话可以看完整个操作流程,统一修改后,一次编译完成。当然,最简单的方法是直接去git仓库clone源码后切换分支进行编译。欢迎各位小伙伴和老司机们进行测试,该仓库会一直维护到官方有类似分支或版本后删除,期待各位的测试结果和问题反馈。

八、写在后面

海纳百川、有容乃大。信创的大背景下,国产硬件、操作系统、数据库、中间件等基础软件行业迎来了春天,这既是机遇又充满了挑战。头部的大厂既是水平领域的竞争对手又是垂直领域的合作伙伴。而作为这个行业的从业者,既要看到我们在基础软件领域的差距,又要砥砺前行,自强不息。

有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴; 与各位共勉。

感谢所有在信创领域一起奋斗的小伙伴们,让我们一起见证国产数据库百花齐放的春天,艳阳高照的夏天和硕果累累的秋天。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
华为OpenEuler认证是华为公司推出的一项认证考试,旨在验证考生对OpenEuler操作系统的理解和应用能力。OpenEuler是华为开源的一个适用于数据库、大数据、云计算、人工智能等应用场景的操作系统。它具有快速灵活、轻量级、可信安全启动、升级不中断业务等技术特性,同时还提供了iSula容器解决方案和A-Tune资源调优自动化等功能。\[2\]在华为OpenEuler认证考试中,考生需要通过单选、多选和判断等题型回答与OpenEuler相关的问题,总分为1000分,600分及格。考试时间为90分钟,共有60个题目。\[1\]通过参加华为OpenEuler认证考试,考生可以证明自己对OpenEuler操作系统的掌握程度,提升自己在相关领域的竞争力。 #### 引用[.reference_title] - *1* [华为认证HCIA-Kunpeng Application Developer单选习题总结](https://blog.csdn.net/weixin_42343931/article/details/106395872)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [鲲鹏HCIA认证之初识鲲鹏(二)](https://blog.csdn.net/chushudu/article/details/106020618)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏 克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值