| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 10 个月前 |
概述
项目成果
本项目已成功在openSUSE Leap 15.6,openSUSE Tumbleweed,SUSE Linux Enterprise Server 15 SP7三个发行版,以及四种支持架构(x86_64, aarch64, ppc64le, s390x)上完成了openGauss 6.0.0软件包的构建、运行和测试工作。
此外,项目构建仓库(含完整的打包脚本、源码和补丁)已被提交至openSUSE Build Service平台,并顺利通过在线验证。同时本项目已被官方运营的server:database类顺利接收通过。具体详情如下:
- 提交
server:database申请请求通过:https://build.opensuse.org/requests/1305598 - 本项目在openSUSE Build Service上的托管地址:https://build.opensuse.org/package/show/server:database/opengauss
- openSUSE官方提供构建输出的下载页面:https://software.opensuse.org/download.html?project=server%3Adatabase&package=opengauss
项目部署与测试
本地编译(可选)
openSUSE Leap 15.6 打包编译方法
-
进行必要的软件源配置(opensuse | 镜像站使用帮助),运行以下命令安装必要软件包:
$ sudo zypper install git git-lfs rpm-build rpmdevtools cmake gcc gcc-c++ openssl-devel python tar unzip liblz4-devel libzstd-devel libboost_headers-devel cJSON-devel libcgroup-devel libcurl-devel bison flex autoconf java-1_8_0-openjdk-devel libedit-devel libaio-devel libxerces-c-devel libxml2-devel unixODBC-devel jemalloc-devel ncurses-devel libboost_thread-devel libboost_atomic-devel libboost_system-devel libboost_chrono-devel -
运行
rpmdev-setuptree设置RPM编译环境 -
下载并部署本项目(注意有git lfs文件)至系统中,将项目中全部文件移动至
~/rpmbuild/SOURCES文件夹下。 -
启动编译:
$ cd ~/rpmbuild/SOURCES $ rpmbuild -ba opengauss-server.spec编译结束后的RPM包位于
~/rpmbuild/RPMS/$(uname -m)/opengauss-6.0.0-24.$(uname -m).rpm -
安装编译好的软件包(可在另外的机器上安装,也可在编译机上安装):
$ sudo zypper install ~/rpmbuild/RPMS/$(uname -m)/opengauss-6.0.0-24.$(uname -m).rpm
SUSE Linux Enterprise Server 15(SLES)打包编译方法
- 激活系统,启用相关软件源,命令行中的版本号和架构请根据实际情况替换
SUSEConnect --product PackageHub/15.7/x86_64
SUSEConnect --product sle-module-legacy/15.7/x86_64
SUSEConnect --product sle-module-desktop-applications/15.7/x86_64
SUSEConnect --product sle-module-development-tools/15.7/x86_64
- 安装软件包
sudo zypper install git-core git-lfs rpm-build rpmdevtools cmake gcc gcc-c++ openssl-devel python tar unzip liblz4-devel libzstd-devel libboost_headers-devel cJSON-devel libcgroup-devel libcurl-devel bison flex autoconf java-1_8_0-openjdk-devel libedit-devel libaio-devel libxerces-c-devel libxml2-devel unixODBC-devel jemalloc-devel ncurses-devel libboost_thread-devel libboost_atomic-devel libboost_system-devel libboost_chrono-devel
- 后续步骤与openSUSE无异
安装
搭建openSUSE Leap 15.6 x86_64虚拟机,目前安装openGauss数据库软件包有两种方式:
- 在线安装:按照 官方指引,输入合适的命令,即可通过
zypper在线安装。 - 离线安装:若因网络原因无法在线安装,可先获取到离线安装包,传输至虚拟机中后,通过
zypper in opengauss-6.0.0.x86_64.rpm进行安装,由于签名密钥未被信任,安装过程需输入i,继续安装。
安装完成后输入systemctl status opengauss即可启动openGauss数据库
测试
在另一台机器上部署benchmarksql-5.0与opengauss专用的JDBC驱动,进行简单压力测试。其中简单的benchmarksql任务配置如下:
conn=jdbc:postgresql://192.168.33.130:7654/tpcctest
user=bot
password=Gaussdba@Mpp
warehouses=5
loadWorkers=10
terminals=20
runTxnsPerTerminal=0
runMins=5
limitTxnsPerMin=0
在服务端创建好所需的用户、数据库,并添加相应的远程访问规则。然后在测试机上运行测试,测试过程中在openGauss服务部署的虚拟机上可以观察到数据库进程的正常运行。最终测试结果如下(2虚拟核心,5GB RAM):
Term-00, Running Average tpmTOTAL: 28250.90 Current tpmTOTAL: 935592 Memory Usage: 44MB / 129MB
18:32:30,078 [Thread-5] INFO jTPCC : Term-00,
18:32:30,078 [Thread-5] INFO jTPCC : Term-00,
18:32:30,078 [Thread-5] INFO jTPCC : Term-00, Measured tpmC (NewOrders) = 12695.42
18:32:30,078 [Thread-5] INFO jTPCC : Term-00, Measured tpmTOTAL = 28244.63
综合来看,本项目编译打包的openGauss 6.0.0顺利通过5分钟压力测试,具备实际可用性。
项目细节
在适配openSUSE的过程中,遇到许多兼容性和规范性问题。为解决这些问题,本项目在基于openEuler原版打包编译脚本的基础上,进行了大量修改,本章主要阐述不断优化打包过程的具体技术细节。
RPM SPEC攥写与rpmlint检查
openSUSE为了确保软件打包的规范性,制定了一系列严格的规则,通过rpmlint工具实施检查。根据RPM SPEC规范,提交openSUSE社区时的审核意见,本项目在SPEC攥写规范上进行了针对性适配,主要包括:
- BuildRequires,Requires标签单行排列,一行只描述一个依赖包
- 大幅削减SPEC指出的Requires数量,减少不必要的运行时依赖,主要通过rpm自带的依赖分析推理得到Requires数据。
__requires_exclude变量仅排除掉内部自带动态库,而不是所有库。- 在编译依赖库时,去除了不常用的编译、链接选项,现在使用编译器默认选项进行。
- 获取编译打包的目标架构时,应通过内置宏
%{_arch}获取。 - 使用
%cmake, %cmake_build, %cmake_install内置宏进行openGauss源码编译,而不是直接调用cmake, make, make install命令。 - 在单独的
%install环节处理安装,%build环节仅处理依赖库及openGauss的编译工作。 - 根据rpmlint检查结果,编写rpmlint过滤规则集:
addFilter(r'(non-standard-gid|non-standard-uid) .* opengauss')
addFilter(r'(postin-without-ldconfig|postun-without-ldconfig) /var/lib/opengauss/pkg_6.0.0/lib/.*')
addFilter(r'shared-lib-calls-exit /var/lib/opengauss/pkg_6.0.0/lib/.*')
addFilter(r'binary-or-shlib-calls-gethostbyname')
addFilter(r'non-standard-group')
addFilter(r'devel-file-in-non-devel-package.* /var/lib/opengauss/pkg_6.0.0/lib/.*.so')
引入外部编译依赖
经过实际调查分析,在openSUSE上编译openGauss,系统软件源无法提供的依赖模块有:xgboost, Huawei Secure C, DCF, aws-sdk-cpp, Kerberos 5,其中Kerberos 5库为openGauss修改定制版。
Kerberos 5的编译过程主要改动点在于,为了支持高版本GCC,单独加上了-std=gnu11选项,以避免编译出错,同时删除不需要安装的目录。具体编译过程如下:
pushd %{krb5_name}-%{krb5_name}-%{krb5_version}
krb5_dir=${dependency_loc}/kerberos/comm
cd src
rm -rf configure; cp %{SOURCE20} ./configure
autoheader; chmod +x configure
./configure CFLAGS='-std=gnu11' --prefix=${krb5_dir} --disable-rpath --disable-pkinit --with-system-verto=no
make %{?_smp_mflags}
make install %{?_smp_mflags}
cd ${krb5_dir}
rm -rf lib/pkgconfig share var
popd
xgboost库的编译过程如下:
pushd %{xgboost_name}-%{xgboost_version}
xgboost_dir=${dependency_loc}/xgboost/comm
rm -rf dmlc-core
cp -r ../dmlc-core-%{dmlc_version}/ ./dmlc-core
cmake . -DCMAKE_INSTALL_PREFIX=${xgboost_dir}
make %{?_smp_mflags}
make install
cp -r ${xgboost_dir} ${dependency_loc}/xgboost/llt
popd
Huawei Securec的编译使用了openGauss-third_party给出的Makefile,为了符合规范,本项目在该Makefile的链接动态库处加入了额外选项:-Wl,-soname=libsecurec.so,确保输出的动态库中包含soname字段。该组件编译过程如下:
pushd %{securec_name}_%{securec_version}
securec_dir=${dependency_loc}/../platform/Huawei_Secure_C/comm
cp %{SOURCE30} ./src/Makefile
make -C src securecstatic securecshare %{?_smp_mflags}
mkdir -p ${securec_dir}
cp -arf include ${securec_dir}
mkdir ${securec_dir}/lib
cp src/libsecurec.a ${securec_dir}/lib/
cp src/libsecurec.a ${securec_dir}/lib/libboundscheck.a
mkdir ${securec_dir}/../Dynamic_Lib
cp src/libsecurec.so ${securec_dir}/../Dynamic_Lib
popd
DCF为openGaus自研组件,主要参考openEular DCF 编译过程实现。在openSUSE编译时遇到编译错误,需合入以下补丁方可解决:
diff --git a/src/election/elc_msg_proc.c b/src/election/elc_msg_proc.c
index 9aa9552..7c3df3d 100644
--- a/src/election/elc_msg_proc.c
+++ b/src/election/elc_msg_proc.c
@@ -179,7 +179,7 @@ bool32 elc_need_demote_follow(uint32 stream_id, timespec_t now, uint32 elc_timeo
uint32 voter_num = 0;
dcf_node_role_t node_list[CM_MAX_NODE_COUNT];
uint32 node_count;
- uint32 local_node_id = md_get_cur_node(stream_id);
+ uint32 local_node_id = md_get_cur_node();
dcf_role_t default_role;
if (elc_stream_get_work_mode(stream_id) != WM_NORMAL) {
return CM_FALSE;
diff --git a/src/common/cm_concurrency/cm_thread.c b/src/common/cm_concurrency/cm_thread.c
index 723b1de..92e0895 100644
--- a/src/common/cm_concurrency/cm_thread.c
+++ b/src/common/cm_concurrency/cm_thread.c
@@ -296,7 +296,7 @@ uint32 cm_get_current_thread_id(void)
#define __SYS_GET_SPID 186
#elif (defined __aarch64__)
#define __SYS_GET_SPID 178
-#elif (defined __loongarch__)
+#else
#include<sys/syscall.h>
#define __SYS_GET_SPID SYS_gettid
#endif
该组件具体编译过程如下:
pushd %{dcf_name}-%{dcf_version}
dcf_dir=${dependency_loc}/../component/dcf
mkdir library
cp -r ${securec_dir} ./library/huawei_security
mkdir -p library/cJSON/include
cp /usr/include/cjson/cJSON.h library/cJSON/include
cmake -S . -B tmp_build -DCMAKE_INSTALL_PREFIX=${dcf_dir} -DCMAKE_BUILD_TYPE=Release -DENABLE_EXPORT_API=OFF -DTEST=OFF
make -C tmp_build %{?_smp_mflags}
mkdir -p ${dcf_dir}
cp -arf ./output/lib ${dcf_dir}/
cp -arf ./src/interface ${dcf_dir}/include
popd
aws-sdk-cpp库主要openEular aws-sdk-cpp 编译过程实现,具体过程如下:
pushd %{awssdk_name}-%{awssdk_version}
awssdk_dir=${dependency_loc}/aws-sdk-cpp/comm
mkdir tmp_build && cd tmp_build
cmake .. -DBUILD_ONLY="s3" \
-DCMAKE_SKIP_RPATH=TRUE \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_INSTALL_PREFIX=${awssdk_dir} \
-DENABLE_TESTING=OFF
make %{?_smp_mflags}
make install
mv ${awssdk_dir}/lib64 ${awssdk_dir}/lib || true
popd
优化openGauss编译过程
在openGaus本体编译打包过程中,为解决openSUSE上特有的编译、运行问题,本项目对原版openGaus 6.0.0代码进行了针对性修改,确保能够在openSUSE上编译、运行通过。
修复CMake配置中的头文件冲突
在openSUSE Tumbleweed系统中,由于使用了高版本的GCC编译器,造成editline/history.h, editline/readline.h头文件与readline.h, readline/history.h, readline/readline.h头文件冲突,导致CMake配置过程中的重要函数CHECK_FOR_MPPDB无法正常运行,进而影响编译。应当将此处的editline/history.h editline/readline.h头文件移除,补丁(og-susebuild.path)节选如下:
diff --git a/cmake/src/build_function.cmake b/cmake/src/build_function.cmake
index fc114c9f2..f22208259 100755
--- a/cmake/src/build_function.cmake
+++ b/cmake/src/build_function.cmake
@@ -395,7 +395,7 @@ function(check_headers_func_c check_include_files check_functions check_decl che
endfunction(check_headers_func_c)
function(CHECK_FOR_MPPDB)
- set(CHECK_INC_FILES crtdefs.h crypt.h dld.h editline/history.h editline/readline.h fp_class.h …… readline.h readline/history.h readline/readline.h …… errno.h)
+ set(CHECK_INC_FILES crtdefs.h crypt.h dld.h fp_class.h …… readline.h readline/history.h readline/readline.h …… errno.h)
set(STDC_HEADERS 1 PARENT_SCOPE)
set(CHECK_FUNCTIONS append_history cbrt ……)
dolphin组件编译
在原版openGaus编译描述文件CMakeLists.txt中,存在如下行:
install(CODE "execute_process(COMMAND bash cmake.sh WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/contrib/dolphin)")
这意味着,dolphin组件是在install阶段通过执行一个脚本进行编译的,由于install过程在单独的环节中执行,且该环节下不应出现编译过程,因而这种策略并不合适。
合理做法是将位于contrib目录下的dolphin组件通过add_subdirectory加入CMakeLists,使之与项目顶层一同配置和编译,具体如下:
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
index 7777f062..8b827394 100644
--- a/contrib/CMakeLists.txt
+++ b/contrib/CMakeLists.txt
@@ -58,3 +65,6 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/datavec)
add_subdirectory(datavec)
endif()
add_subdirectory(gms_profiler)
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/dolphin)
+ add_subdirectory(dolphin)
+endif()
\ No newline at end of file
同时修改了contrib/dolphin/CMakeLists.txt的目录变量,将CMAKE_SOURCE_DIR全部修改为CMAKE_CURRENT_SOURCE_DIR,确保相关变量能够正确指向openGauss源代码根目录,具体如下:
diff --git a/contrib/dolphin/CMakeLists.txt b/contrib/dolphin/CMakeLists.txt
index 4a606c78..b9a87a76 100755
--- a/contrib/dolphin/CMakeLists.txt
+++ b/contrib/dolphin/CMakeLists.txt
@@ -38,11 +38,11 @@ if("${ENABLE_PRIVATEGAUSS}" STREQUAL "ON")
endif()
#FIXME: make it an argument
-set(openGauss "../..")
-set(ENV{openGauss} "../..")
+set(openGauss ".")
+set(ENV{openGauss} ".")
#------------------------------------------------------------------------------------
-set(PROJECT_TRUNK_DIR ${CMAKE_SOURCE_DIR}/../..)
+set(PROJECT_TRUNK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../..)
set(PROJECT_OPENGS_DIR ${PROJECT_TRUNK_DIR} CACHE INTERNAL "")
# PROJECT_TRUNK_DIR: ./
@@ -75,7 +75,7 @@ endif()
message(WARNING "dolphin cmake begin")
-set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../../cmake/src)
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/src)
include(build_function)
include(set_thirdparty_path)
针对dolphin编译修改的更多内容汇总在构建仓下的og-dolphin.patch补丁中。全部修改到位后,可实现dolphin组件在%build阶段与openGaus一起配置和编译。
多架构支持
对于非x86_64和aarch64架构而言,需在原版openGaus代码中修改部分内容,才能确保在openSUSE支持的ppc64le, s390x架构上编译运行通过。该部分所有修改汇总于补丁og-more-arch-support.patch中。
特殊指令兼容性问题。在CRC32计算过程中使用了SSE4.2指令集,需在CMakeFiles中移除使用该指令集的源代码文件,具体补丁节选如下:
diff --git a/src/common/port/CMakeLists.txt b/src/common/port/CMakeLists.txt
index b9a6a28..e511eb0 100755
--- a/src/common/port/CMakeLists.txt
+++ b/src/common/port/CMakeLists.txt
@@ -90,10 +90,31 @@ if("${BUILD_TUPLE}" STREQUAL "aarch64")
set(TGT_crc32_arm_parallel_SRC ${CMAKE_CURRENT_SOURCE_DIR}/crc32_arm_parallel.S)
endif()
+if("${BUILD_TUPLE}" STREQUAL "ppc64le")
+ list(REMOVE_ITEM TGT_port_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_choose.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_sse42.cpp)
+endif()
+
+if("${BUILD_TUPLE}" STREQUAL "s390x")
+ list(REMOVE_ITEM TGT_port_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_choose.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_sse42.cpp)
+endif()
SET(TGT_pgport_INC
${PROJECT_SRC_DIR}/common/backend
${PROJECT_SRC_DIR}/common/port
大小端字节序适配问题。由于s390x平台为大端字节序(其余架构都为小端序),而openGaus在开发过程中未针对大端序进行充分考量,导致服务程序gaussdb在运行中会因为锁(LWLock)而卡死。在SPEC中,当目标架构为s390x时,会向CMake命令传入-DWORDS_BIGENDIAN=ON选项,强制指定当前为大端序运行平台,随后还需修改以下操作锁(LWLock,BufferDesc)的代码,具体补丁节选如下:
diff --git a/src/gausskernel/storage/lmgr/lwlock.cpp b/src/gausskernel/storage/lmgr/lwlock.cpp
index d84b4334..7b547c4d 100644
--- a/src/gausskernel/storage/lmgr/lwlock.cpp
+++ b/src/gausskernel/storage/lmgr/lwlock.cpp
@@ -893,7 +893,13 @@ static bool LWLockAttemptLock(LWLock *lock, LWLockMode mode)
if ((desired_state & (LW_VAL_EXCLUSIVE)) != 0) {
return true;
}
- } while (!pg_atomic_compare_exchange_u8((((volatile uint8*)&lock->state) + maskId), ((uint8*)&old_state) + maskId, (desired_state >> (8 * maskId))));
+ } while (!pg_atomic_compare_exchange_u8(
+#ifndef WORDS_BIGENDIAN
+ (((volatile uint8*)&lock->state) + maskId), ((uint8*)&old_state) + maskId,
+#else
+ (((volatile uint8*)&lock->state) + sizeof(lock->state) - maskId - 1), ((uint8*)&old_state) + sizeof(lock->state) - maskId - 1,
+#endif
+ (desired_state >> (8 * maskId))));
} else if (mode == LW_EXCLUSIVE) {
old_state = pg_atomic_read_u64(&lock->state);
do {
diff --git a/src/gausskernel/storage/buffer/bufmgr.cpp b/src/gausskernel/storage/buffer/bufmgr.cpp
index c6a4c2c2..3b71a381 100644
--- a/src/gausskernel/storage/buffer/bufmgr.cpp
+++ b/src/gausskernel/storage/buffer/bufmgr.cpp
@@ -1962,7 +1962,13 @@ Buffer ReadBuffer_common_for_localbuf(RelFileNode rnode, char relpersistence, Fo
Assert(buf_state & BM_VALID);
buf_state &= ~BM_VALID;
- pg_atomic_write_u32(((volatile uint32 *)&bufHdr->state) + 1, buf_state >> 32);
+ pg_atomic_write_u32(
+#ifndef WORDS_BIGENDIAN
+ ((volatile uint32 *)&bufHdr->state) + 1,
+#else
+ ((volatile uint32 *)&bufHdr->state),
+#endif
+ buf_state >> 32);
}
/*
该问题的根源是使用8bit的读写操作去尝试读/写64bit(或32bit)长度内存数据的低8位时,由于大小端字节序的低8位数据的内存地址计算方式不同,进而产生意料之外的内存读写。
全部应用以上修改后,openGaus可以在ppc64le, s390x架构上顺利运行。
打包安装脚本
根据在openSUSE Build Service上给出的rpmlint检查结果,进一步优化SPEC文件中的%install环节,具体如下:
- 优化文件权限分配,仅对
bin, lib文件夹下的程序和库分配可执行权限,其余文件不再赋予可执行权限。 - 优化重复文件,主要通过
%fdupes宏将重复文件互相链接,降低空间占用。 - 删除无用的静态库和头文件,降低空间占用。
- 去除以下调用separate_debug_symbol.sh分离符号的过程,该过程由rpm在编译、安装后可自动完成。
cd ${opengauss_source_dir}/build/script chmod +x ./separate_debug_information.sh sed -i '/"$BIN_DIR\/gaussdb\.map"/d' ./separate_debug_information.sh ./separate_debug_information.sh - 去除以下将编译产物整体压缩的过程:
由于openSUSE Build Service平台会对cd ${opengauss_source_dir}/mppdb_temp_install tar -zcf ${kernel_package_name}.tar.bz2 * sha256sum ${kernel_package_name}.tar.bz2 | awk '{print $1}' > ${kernel_package_name}.sha256%post脚本进行重复执行,还需修改升级脚本,确保同版本升级时不会报错导致异常退出。
总结与展望
本项目聚焦于将openGauss 6.0.0集成至openSUSE生态系统,旨在提升openGauss在SUSE系发行版中的可访问性与部署效率。
在项目周期内,已成功在openSUSE Leap 15.6、openSUSE Tumbleweed及SUSE Linux Enterprise Server 15 SP7三大主流SUSE系发行版上完成openGauss 6.0.0的软件包构建、安装、运行与功能验证。通过对软件源代码的分析与调试,实现了对x86_64、aarch64、ppc64le和s390x四种关键架构的全面支持,确保了openGauss在不同硬件平台上的兼容性与可用性。
项目构建仓库(含完整的打包脚本、源码和补丁)已成功提交至openSUSE Build Service(OBS)平台,并通过了OBS的在线构建与验证流程(如图1所示),确保了构建过程的自动化与可复现性。且项目成果已通过openSUSE官方server:database项目组的审核与接纳(如图2所示),这将为openGauss在SUSE生态系统下的维护与推广奠定了坚实基础。