OceanBase是由蚂蚁集团、阿里巴巴完全自主研发的分布式关系型数据库,始创于2010年。
OceanBase具有数据强一致、高可用、高性能、在线扩展、高度兼容SQL标准和主流关系型数据库、低成本等特点
您能获得什么
通过本系列的源码解读文章,您首先可以了解 OceanBase 数据库的基本原理,学到一个数据库是如何实现的。推而广之,您也可以把 OceanBase 的实现原理应用到其他数据库,这对您学习其他数据库也有帮助。其次,在熟悉了 OceanBase 的代码之后,如果有需要,您可以直接在未来的工作中使用我们的代码,或者为 OceanBase 贡献您的代码
今天 分析:执行过程
bash build.sh debug --init --make
1. build.sh --init 调用 main
2. main 执行 do_init
3. do_init 完成后进入 CMake 配置
4. CMake 加载配置文件
5. 输出配置信息
6. 检查依赖
生成构建系统
Check the Install toolchain guide for supported OS, GLIBC version requirement, and how to install the C++ toolcha
https://oceanbase.github.io/oceanbase/toolchain/
CentOS编译
# 1. 初始化依赖
./build.sh --init
# 2. 选择编译模式(debug/release等)
./build.sh debug --make
./build.sh release --make
# 必需的基础软件包
yum install -y \
gcc \
gcc-c++ \
make \
glibc-devel \
libstdc++-devel \
git \
wget \
perl \
tar \
bzip2 \
which
# GCC版本要求
- 默认支持C++11标准 (代码中 CPP_STANDARD_OPTION=11)
- 如果使用-DCPP_STANDARD_20=ON,则需要支持C++20标准的GCC版本
# 推荐GCC版本
- CentOS 7: GCC 4.8.5及以上
- CentOS 8: GCC 8.x及以上
# 硬件资源
- CPU: 建议4核及以上(编译会使用所有可用核心 grep -c ^processor /proc/cpuinfo)
- 内存: 建议16GB及以上
- 磁盘空间: 建议50GB及以上(用于源码、依赖和编译输出)
# 系统配置
- 最大文件打开数: ulimit -n 65535
- 最大用户进程数: ulimit -u 65535
# 核心依赖包
yum install -y \
libaio-devel \
openssl-devel \
bzip2-devel \
zlib-devel \
ncurses-devel \
libcurl-devel \
readline-devel \
mariadb-devel \
boost-devel
# 如果使用RPM打包还需要
yum install -y \
rpm-build \
rpmlint
- 脚本会使用工具目录中的CMake: ${TOOLS_DIR}/bin/cmak
./build.sh --init
↓
main "$@" 。//$@ 是一个特殊变量,代表脚本运行时传递的所有命令行参数
↓
parse_args # 设置NEED_INIT=true
↓
do_init # 执行初始化
在 Shell 脚本中,main "$@"
是一种常见的用法,用于定义一个 main
函数并传递所有的命令行参数给它。让我们详细了解这部分的含义:
递 ./script.sh arg1 "arg two" arg3
,"$@"
将解析为 arg1
、arg two
、arg3
。
"$*"
把所有参数拼接成一个字符串处理。"$@"
保留了参数的独立性,每个参数单独处理。用法示例
示例脚本
#!/bin/bash
main() {
echo "Number of arguments: $#"
echo "Arguments:"
for arg in "$@"; do
echo "$arg"
done
}
# Call the main function and pass all command-line arguments
main "$@"
./script.sh arg1 "arg two" arg3
Number of arguments: 3
Arguments:
arg1
arg two
arg3
# parse arguments
ALL_ARGS=("$@") //这个是一个数组
function parse_args
{
for i in "${ALL_ARGS[@]}"; do//ALL_ARGS[@] 全部元素 {}集合
if [[ "$i" == "--init" ]]
then
NEED_INIT=true
}
#!/bin/bash
# 定义一个数组
ALL_ARGS=("arg1" "arg2" "arg3" "arg with spaces")
# 遍历数组中的每个元素
for i in "${ALL_ARGS[@]}"; do
echo "Current argument: $i"
done
# dep_create
TOPDIR=`readlink -f \`dirname $0\``
function do_init
{
export CPP_STANDARD=${CPP_STANDARD_OPTION} //C++ 标准库的版本 为11
time1_ms=$(echo $[$(date +%s%N)/1000000]) //脚本开始执行的时间
(cd $TOPDIR/deps/init && bash dep_create.sh)
//$TOPDIR 是一个预定义的环境变量,通常指向项目根目录
//进入 deps/init 目录并执行 dep_create.sh 脚本
if [ $? -ne 0 ]; then
exit $?
fi
time2_ms=$(echo $[$(date +%s%N)/1000000]) //脚本开始执行的时间
}
补充:
代码:
TOPDIR=`readlink -f \`dirname $0\``
的作用是获取当前脚本所在的绝对路径,并将其赋值给变量 TOPDIR
。
$0
:$0
是一个特殊变量,表示脚本的名称或脚本被执行时的路径。$0
会包含该脚本的路径或仅包含文件名,取决于你如何调用脚本。dirname $0
:dirname
是一个命令,用于返回给定路径的目录部分。/home/user/script.sh
,dirname $0
将返回 /home/user
。dirname $0
会先被执行,获取脚本的目录路径。readlink -f
:readlink -f
命令返回指定路径的绝对路径。如果路径是符号链接,-f
选项会跟踪符号链接,返回最终的实际路径。dirname $0
获取脚本文件所在的目录路径。readlink -f
将该目录路径转化为绝对路径,解决了相对路径和符号链接的问题。TOPDIR
变量将存储脚本所在的目录的绝对路径。假设脚本的路径是 /home/user/projects/script.sh
,当你运行这行命令时:
dirname $0
会返回 /home/user/projects
。readlink -f /home/user/projects
由于已经是绝对路径,结果仍然是 /home/user/projects
。TOPDIR
的值将是 /home/user/projects
。unalias -a
PWD="$(cd $(dirname $0); pwd)"
OS_ARCH="$(uname -m)" || exit 1
OS_RELEASE="0"
AL3_RELEASE="0"
unalias -a
:清除所有的 alias(别名),避免干扰后续命令。PWD
:获取脚本所在的当前绝对路径。OS_ARCH
:使用 uname -m
获取系统架构(例如 x86_64
)。OS_RELEASE
和 AL3_RELEASE
为 0
。if [[ ! -f /etc/os-release ]]; then
echo "[ERROR] os release info not found" 1>&2 && exit 1
fi
source /etc/os-release || exit 1
/etc/os-release
文件是否存在,如果没有该文件,输出错误信息并退出。/etc/os-release
文件,获取系统的详细信息(例如 NAME
, VERSION
, ID
, VERSION_ID
等),并将其加载到当前 shell 环境中。定义了多个函数来根据不同操作系统(如 CentOS、AlmaLinux、Ubuntu 等)设置适当的版本标识:
function compat_centos9() { ... }
function compat_centos8() { ... }
function compat_centos7() { ... }
function compat_alinux3() { ... }
每个函数会根据系统信息输出相关信息,并设置 OS_RELEASE
和 AL3_RELEASE
。
function get_os_release() { ... }
get_os_release || exit 1
get_os_release
函数检查系统的架构和版本,通过比较操作系统的 ID 和版本来确定操作系统的兼容性,并根据系统架构和版本设置 OS_RELEASE
和 AL3_RELEASE
。DEP_FILE="oceanbase.${OS_TAG}.deps"//oceanbase.el8.x86_64.deps
MD5=`md5sum ${DEP_FILE} | cut -d" " -f1`
DEP_FILE
是包含依赖信息的文件,格式为 oceanbase.${OS_TAG}.deps
,其中 OS_TAG
基于操作系统和架构动态生成。DEP_FILE
的 MD5 值,以便后续判断是否使用缓存。if [ -f ${WORKSAPCE_DEPS_3RD_MD5} ]; then
...
fi
if [ "x${DEP_CACHE_DIR}" == "x" ]; then
NEED_SHARE_CACHE=OFF
echo_log "disable share dep cache due to env DEP_CACHE_DIR not set"
fi
DEP_CACHE_DIR
,若未设置,则禁用缓存。if [ ${NEED_SHARE_CACHE} == "ON" ]; then
...
fi
mkdir -p "${TARGET_DIR_3RD}/pkg"
for sect in "${!packages[@]}"
do
...
wget "$repo/${pkg}" -O "${TARGET_DIR_3RD}/pkg/${TEMP}" &> ${TARGET_DIR_3RD}/pkg/error.log
done
DEP_FILE
中的内容(依赖列表),循环下载每个依赖包。wget
下载依赖包到 TARGET_DIR_3RD/pkg/
目录。rpm2cpio
或 rpmextract.sh
解压依赖包。if [ ${LINK_CHACE_DIRECT} == "ON" ]; then
ln -sf ${CACHE_DEPS_DIR_3RD} ${WORKSPACE_DEPS_3RD}
exit $?
fi
touch ${CACHE_DEPS_LOCKFILE}
chmod 777 ${CACHE_DEPS_LOCKFILE}
echo_log "generate lock file ${CACHE_DEPS_LOCKFILE}"
rm -rf ${CACHE_DEPS_LOCKFILE}
echo_log "unlock lock file ${CACHE_DEPS_LOCKFILE}"
touch ${WORKSAPCE_DEPS_3RD_MD5}
touch ${WORKSAPCE_DEPS_3RD_DONE}
touch ${WORKSAPCE_DEPS_3RD_CPP_STANDARD}
.DONE
和 .CPP_STANDARD
文件以标识缓存初始化完成。执行顺序:
build.sh 首先调用 dep_create.sh 安装依赖
dep_create.sh 完成后,CMake使用 env.cmake 配置编译环境
env.cmake 使用 dep_create.sh 创建的环境进行编译配置
依赖关系:
dep_create.sh 负责准备编译环境
env.cmake 负责使用这个环境
两者需要保持配置的一致性执行顺序:
# make build directory && cmake && make (if need)
function do_build
{
if [ ! -f ${TOOLS_DIR}/bin/cmake ]; then
echo_log "[NOTICE] Your workspace has not initialized dependencies, please append '--init' args to initialize dependencies"
exit 1
fi
TYPE=$1; shift
prepare_build_dir $TYPE || return
${CMAKE_COMMAND} ${TOPDIR} "$@" -DCPP_STANDARD_20=$CPP_STANDARD_20_OPTION
if [ $? -ne 0 ]; then
echo_err "Failed to generate Makefile"
exit 1
fi
}
./build.sh --init
./build.sh --init
[dep_create.sh] [NOTICE] 'Ubuntu 22.04.5 LTS (x86_64)' is compatible with CentOS 9, use el9 dependencies list
[dep_create.sh] oceanbase.el9.x86_64.deps has been initialized due to /workspace/oceanbase/deps/3rd/e9982c3dd04198e4728809c2bf18f7c5, /workspace/oceanbase/deps/3rd/DONE and /workspace/oceanbase/deps/3rd/CPP_11 exists
[build.sh] use dep_create.sh to create deps cost time: 0m0s
-- Using C++11 standard
-- build with pie
-- Using OB_CC compiler: /workspace/oceanbase/deps/3rd/usr/local/oceanbase/devtools/bin/clang
-- Using OB_CXX compiler: /workspace/oceanbase/deps/3rd/usr/local/oceanbase/devtools/bin/clang++
-- ob-compile not found, compile locally.
-- open source build enabled
-- This is BINARY dir /workspace/oceanbase
-- This is SOURCE dir /workspace/oceanbase
-- check deps for libeasy
-- This is BINARY dir /workspace/oceanbase/deps/oblib
-- This is SOURCE dir /workspace/oceanbase/deps/oblib
-- oblib_add_library compress
-- oblib_add_library zstd
-- oblib_add_library zstd_1_3_8
-- oblib_add_library lz4
-- oblib_add_library snappy
-- zlib_lite use qpl
-- oblib_add_library zlib_lite
-- oblib_add_library restore
-- oblib_add_library s3
-- oblib_add_library cos_sdk
-- ob_lib_add_target oblib_lib_simd
-- ob_lib_add_target oblib_lib
-- ob_lib_add_target oblib_lib_bitmap
-- ob_add_new_object_target ob_malloc_object
-- ob_lib_add_target oblib_common
-- ob_lib_add_target oblib_rpc
-- oblib_extra_objects /workspace/oceanbase/deps/oblib/src/lib/compress/zstd/zstd_objs.o;/workspace/oceanbase/deps/oblib/src/lib/compress/zstd_1_3_8/zstd_1_3_8_objs.o;/workspace/oceanbase/deps/oblib/src/lib/compress/lz4/lz4-all.a.o;/workspace/oceanbase/deps/oblib/src/lib/compress/zlib_lite/zlib_lite_objs.o;/workspace/oceanbase/deps/oblib/src/lib/restore/cos/cos_sdk_objs.o
-- /workspace/oceanbase/deps/3rd
-- This is BINARY dir /workspace/oceanbase/src/objit
-- This is SOURCE dir /workspace/oceanbase/src/objit
-- Building with -fPIC
-- ob_add_new_object_target ob_share
-- ob_add_new_object_target ob_sql
-- observer_add_target ob_sql_simd
-- generating /workspace/oceanbase/src/share/inner_table/sys_package/system_package.cpp ...
-- generate /workspace/oceanbase/src/share/inner_table/sys_package/system_package.cpp done
-- observer_add_target ob_pl
-- observer_add_target ob_rootserver
-- observer_add_target ob_logservice
-- ob_add_new_object_target oblogminer_objs
-- ob_add_new_object_target oblogminer_obj_dev
-- ob_add_new_object_target obcdc_objects
-- ob_add_new_object_target obcdc_objects_miner
-- ob_add_new_object_target obcdc_tailf_objects
-- ob_add_new_object_target obcdc_tailf_objects_static
-- ob_add_new_object_target ob_storage
-- observer_add_target ob_storage_simd
-- observer_add_target ob_diagnose_lua
-- observer_add_target ob_server
-- ob_add_new_object_target obtable_base_objects
-- Configuring done (0.5s)
-- Generating done (4.1s)
-- Build files have been written to: /workspace/oceanbase
deps/
├── 3rd/
│ └── usr/
│ └── local/
│ └── oceanbase/
│ ├── deps/
│ │ └── devel/
│ │ ├── openssl -> /usr/local/opt/openssl
│ │ ├── boost -> /usr/local/opt/boost
│ │ └── mariadb -> /usr/local/opt/mariadb-connector-c
│ └── devtools/
│ └── bin/
│ ├── cmake -> /usr/local/opt/cmake/bin/cmake
│ ├── clang -> /usr/local/opt/llvm/bin/clang
│ └── clang++ -> /usr/local/opt/llvm/bin/clang++
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。