引子

由于时间和精力的原因,上一篇关于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) 8 16G 40G

操作系统信息

[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" ]]; thencase "$ID" inalinux)version_ge "2.1903" && compat_centos7 && return;;alios)version_ge "8.0" && compat_centos8 && returnversion_ge "7.2" && compat_centos7 && return;;anolis)version_ge "8.0" && compat_centos8 && returnversion_ge "7.0" && compat_centos7 && return;;ubuntu)version_ge "16.04" && compat_centos7 && return;;centos)version_ge "8.0" && OS_RELEASE=8 && returnversion_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;;#susesles)version_ge "15" && compat_centos7 && return;;uos)version_ge "20" && compat_centos7 && return;;esacelif [[ "${OS_ARCH}x" == "aarch64x" ]]; thencase "$ID" inalios)version_ge "8.0" && compat_centos8 && returnversion_ge "7.0" && compat_centos7 && return;;centos)version_ge "8.0" && OS_RELEASE=8 && returnversion_ge "7.0" && OS_RELEASE=7 && return;;esacfi

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

[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" ]]; thencase "$ID" inalios)version_ge "8.0" && compat_centos8 && returnversion_ge "7.0" && compat_centos7 && return;;centos)version_ge "8.0" && OS_RELEASE=8 && returnversion_ge "7.0" && OS_RELEASE=7 && return;;# add for openEuler by ShylockopenEuler)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 observerlinux-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.cCMake Error at src/sql/parser/CMakeLists.txt:65 (add_library):No SOURCES given to target: ob_sql_proxy_parser_objectsCMake Error at src/sql/parser/CMakeLists.txt:93 (add_library):No SOURCES given to target: ob_sql_server_parser_staticCMake Error at src/sql/parser/CMakeLists.txt:72 (add_library):No SOURCES given to target: ob_sql_server_parser_objectsCMake 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源码后切换分支进行编译。欢迎各位小伙伴和老司机们进行测试,该仓库会一直维护到官方有类似分支或版本后删除,期待各位的测试结果和问题反馈。

八、写在后面

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

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

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

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

  1. RK系列开发板音频驱动适配指南(二)

    背景: 上一篇文章RK系列开发板音频驱动适配指南-DAI模块适配中已经阐述音频驱动适配的DAI模块适配步骤以及核心代码的展示,本次主要介绍音频驱动适配中的DMA模块适配. RK系列开发板 DMA模块适 ...

  2. 从YARN迁移到k8s,滴滴机器学习平台二次开发是这样做的

    整理 | 夕颜 出品 | AI科技大本营(ID:rgznai100) [导读]人工智能时代,机器学习已经渗透进每个领域,改变了这些领域的业务模式.技术架构以及方法论.随着深度学习技术近年来快速发展,高 ...

  3. 答网友提问:使用 SAP Fiori Tools 创建的 Fiori Elements 应用,如何进行二次开发?

    这是 Jerry 2021 年的第 28 篇文章,也是汪子熙公众号总共第 299 篇原创文章. Jerry 之前的文章 在没有任何前端开发经验的基础上, 创建第一个 SAP Fiori Element ...

  4. 【Arduino】OTTO机器人(做二次开发的一点点总结)

    偶然一个机会得以接触一下Arduino,了解一下Arduino代码的编写模式,接触了C++函数封装,算是真正接触了一下项目开发,也意识到项目开发中的种种问题不是写代码能解决的,在阅读别人代码时也需要有 ...

  5. 2021年3月7日 蚂蚁金服的OceanBase Java后端开发实习面经(一面)

    title: 2021年3月7日 蚂蚁金服的OceanBase Java后端开发实习面经(一面) tags: 面经 2021年3月7日 蚂蚁金服的OceanBase Java后端开发实习面经(一面) ...

  6. 大数据管理神器:Ambari自定义stack和服务二次开发详细教程

    背景 Ambari 是 Apache Software Foundation 的一个顶级开源项目,是一个集中部署.管理.监控 Hadoop 分布式集群的工具. 部署:自动化部署 Hadoop 软件,能 ...

  7. 转载-大数据管理神器:Ambari自定义stack和服务二次开发详细教程

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/ZYC88888/article/det ...

  8. postek二次开发_博思得RFID标签打印机解析

    [IT168厂商动态]近年来,物联网作为我国战略发展新兴行业,物联网概念持续升温,作为推进物联网发展的关键技术之一RFID无线射频技术,也随之形成高速发展和广泛应用的局面.POSTEK博思得作为国内领 ...

  9. CSDN直播预告丨“0成本”、可二次开发的开源OA开发平台,你是时候来了解下了!

    双城记中有一句话,大家应该都耳熟能详:"这是最好的时代,也是最坏的时代". 这句话无论放在哪个时代都是适用的,就拿我们当前职场生活举例: 在传统的办公模式下,打卡用着传统的打卡机, ...

最新文章

  1. 将功能绑定到Twitter Bootstrap Modal关闭
  2. javascript编程风格
  3. UA OPTI501 电磁波4 电介质及其极化
  4. 【BZOJ】2982 combination
  5. 【快乐水题】594. 最长和谐子序列
  6. Test Article
  7. linux 运行eclipse,解决Linux下Eclipse启动错误
  8. 崭新的2020(洛谷P5886题题解,Java语言描述)
  9. jquery-weui滚动加载问题解决
  10. Codeforces 754A(搜索)
  11. Windows下安装Nginx+php+mysql环境
  12. Linux系统压缩解压缩
  13. 11年艺术学习“转投”数学,他出版首本TensorFlow中文教材,成为蚂蚁金服技术大军一员
  14. 搜狗高级测试经理诸葛东明谈基于AI图像识别的输入法性能测试实践
  15. exports生效 nfs_共享存储Nfs使用
  16. 批量修改文件夹中文件的后缀名
  17. 企业员工快速增长,无线网络如何承载需求?干货!
  18. JAVA学习数据库2
  19. 云计算在美国的五年是如何发展的?
  20. php-gtk2怎么用,PHP+GTK2 初体验,简单计算器客户端

热门文章

  1. CSS(3)学习笔记——持续更新
  2. ocaml-----hello world
  3. 华为鸿蒙布局发展大会,华为开发者大会:全球瞩目的“鸿蒙”面子和里子大格局...
  4. 从王者荣耀看设计模式(虚拟代理模式)
  5. 智云通CRM:做销售需要保持沟通的不紧迫感?
  6. 中国智能全轮驱动系统行业市场供需与战略研究报告
  7. “自动修复“无法修复你的电脑,日志文件:C:\Windows\System32\Logfiles\Srt\SrtTrail.txt
  8. 数据分析与SAS学习笔记8
  9. MFC开发——点击页面生成图标功能
  10. 沣东新城计算机中心,科技引领轴崛起新地标,沣东新城新中心即将诞生