前言
在tidb的所有组件中,使用rust编写的tikv是比较有代表性的一个组件。
rust目前使用的人比较少,再加上tikv编译过程中使用的工具比较多,在论坛上经常碰到一些tikv的编译问题,难以解决。
另外在windows环境下,开发和学习tikv也不如linux环境下便利,WSL对这个问题有很大的改善,也兼顾着介绍一下。
文本希望提供一种一步接一步的方式,让任何没有编译安装经验的人,都能成功编译tikv。
WSL(Windows Subsystem for Linux)
在windows环境下,要使用linux的一些工具是比较麻烦的,以前的做法基本都是通过虚拟机(VMware, Hyper-V),不过这类虚拟机产品一般会有资源固定,随用随扩的能力比较差,网络设置复杂(特别是现在很多开发工作不科学上网根本寸步难行,本来就别扭的网络设置还要考虑代理的问题,就更复杂),访问虚拟机内外的资源互通困难,等等问题。微软在这种情况下,推出了WSL。
这里不介绍WSL的具体安装,具体的安装方法可以看
https://www.bilibili.com/video/BV1tW42197za
而WSL的官方文档地址:https://learn.microsoft.com/zh-cn/windows/wsl/
需要系统了解的,可以翻看。
另外需要准备好科学上网的工具,后面离不开它。
我们从已经装好了WSL开始。
当你安装好了WSL,直接在运行-》cmd之后,打开的命令行界面里,就可以
wsl --version
另外需要详细了解wsl命令包含那些参数,可以使用 wsl --help
查看
看到上面这个界面。之后使用
wsl -l --online
这就是当前支持的分发版本。如果需要rocky,或者centos,参考官方文档
https://learn.microsoft.com/zh-cn/windows/wsl/use-custom-distro
这部分内容。本文使用的分发版本是ubuntu-24.04。
上面的列出的linux分发版本都可以使用wsl --install <Distro>
直接安装(需要科学上网),但如果你的c盘和我一样不富裕的话,还是建议使用
wsl --install Ubuntu-24.04 --location D:\wsl\Ubuntu24
这种安装方式,location后面就是这个wsl存储文件的所在地址。
值得一提的是,这里的存储是随用随扩的,上限可以在wsl settings里面设置。没用到的时候,实际的文件并不大,到编译完成,这个空间会用到10g左右。
等待下载结束,安装之后设置好用户名密码,就可以进入ubuntu24的环境里面了。
前面的提示符会变化,无缝进入linux环境。
WSL的网络设置
因为使用了科学上网,在wsl里面也是需要访问外网的。所以还要做一番网络设置。
直接找 wsl settings
,
把网络模式从NAT,改成Mirrored。在我这个wsl版本下我没有做其他修改,如果不能访问,对着这个界面看看哪里设置不一致。
编译Tikv
安装工具和必要的库
rustup
首先是rustup,
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
中途会问你是否需要定制化安装,这里不需要定制化安装,直接回车。
装完了提示你要修改一些环境变量,以便能在PATH中找到rustup。
最后rustup -V
之后能看到类似的输出就是设置的没问题了。
编译工具
主要是make,cmake,clang,llvm,gcc-9,g++-9,apt安装前,需要先sudo apt update一下,之后
sudo apt install build-essential cmake clang llvm gcc-9 g++-9
最后安装版本如下:
gcc,g++的版本安装的时候就指定了,就是9。
其他必要的库
sudo apt install libssl-dev pkg-config libsnappy-dev librocksdb-dev libgrpc++-dev
这些必要的库,也需要提前装好。
开始编译
先把代码弄下来
git clone https://github.com/tikv/tikv.git
cd tikv
我把tikv放在了/mnt/e下面。这个/mnt/e值得提一下,其实这里访问的是windows系统下的e盘。使用wsl的时候,你的系统里面的每个盘符都会自动被wsl挂在/mnt目录下面。
也就是说,我把编译工具和编译的库,装在一个ubuntu24的虚拟机里面,但是把tikv代码放在了windows的存储里面。两者通过/mnt目录可以实现相互访问。只在ubuntu24里面放不得不在linux下运行的文件。
当然你也可以放在其他目录,比如/opt,,只要是非/mnt/{盘符}这样的路径,你其实是把tikv的代码放在了安装ubuntu24指定的location参数指向的那个文件里面,上面可以看到是d:\wsl\ubuntu24\ext4.vhdx
。这会导致这个文件随着使用而增大,而且你通过wsl --unregister删除这个ubuntu24的分发版本的时候,这个tikv的代码也就跟着d:\wsl\ubuntu24\ext4.vhdx
文件的删除一起没了。
WSL的优势就是让linux和windows有一种浑然一体的感觉。相互访问非常方便。
现在万事具备,直接
make build
注意这里不要使用cargo build。rust项目会使用cargo build是没错。但是make脚本里面需要设置rustc的版本,如果你第一次运行make build,发现卡住一阵,没有任何输出,你top一下就能看到rustc/rustup占用的cpu最高。这就是在设置rustc的版本,如果对应的rustc版本没有安装,会自动安装,设置好rustc的版本继续编译。
以前在论坛上碰到过一些因为rustc版本设置不正确导致的莫名报错。当时我还不知道怎么解决,我现在意识到,这可能就是直接使用cargo build而没有使用make build造成的。
然而并不顺利,编译会这附近停止,
然后跳出一个几千行的报错。没错,是几千行。初次见到会有点吓人。不要慌,冷静看看有什么值得注意的信息。
[ 9%] Building C object third_party/cares/cares/CMakeFiles/c-ares.dir/ares_parse_mx_reply.c.o
[ 9%] Building C object third_party/cares/cares/CMakeFiles/c-ares.dir/ares_parse_naptr_reply.c.o
gmake[4]: Entering directory '/mnt/e/tikv/target/x86_64-unknown-linux-gnu/debug/build/grpcio-sys-45d0a6dfc49c8631/out/build'
类似这种前面带[ 9%]
,其实是正常的编译进度信息,只是报错了以后才打印出来,用于排除错误的,可以直接忽略。继续往下翻,
336 | constexpr FormatConversionCharSet FormatConversionCharSetUnion(
| ^~~~~~~~~~~~~~~~~~~~~~~
| FormatConversionCharInternal
/home/yao/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/grpcio-sys-0.10.3+1.44.0-patched/grpc/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h:342:11: error: 'FormatConversionCharSet' does not name a type; did you mean 'FormatConversionCharInternal'?
342 | constexpr FormatConversionCharSet FormatConversionCharSetUnion(
| ^~~~~~~~~~~~~~~~~~~~~~~
| FormatConversionCharInternal
/home/yao/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/grpcio-sys-0.10.3+1.44.0-patched/grpc/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h:349:11: error: 'uint64_t' does not name a type
值得注意的上面这种信息,这说明编辑器着急的快要亲自下场教你该怎么改了。
把上述报错贴给deepseek,给出的方法是gcc的版本可能设置的不对。gcc9我们上面已经装了,gcc --version显示还是13.
所以需要通过环境变量设置一下
export CC=gcc-9
export CXX=g++-9
之后继续make build,就没有这个错误了。
直到最后一步link的时候又报错了。这次报错没有前面那么离谱,也有1-200行,不过前面大部分是告诉你具体是怎么link的。不用管。直奔最后
= note: some arguments are omitted. use --verbose to show all linker arguments
= note: rust-lld: error: undefined symbol: rocksdb::encryption::NewKeyManagedEncryptedEnv(rocksdb::Env*, std::shared_ptrrocksdb::encryption::KeyManager&)
>>> referenced by c.cc
>>> fe2781a27f0c2488-c.o:(crocksdb_key_managed_encrypted_env_create) in archive /mnt/e/tikv/target/x86_64-unknown-linux-gnu/debug/deps/liblibrocksdb_sys-5c81777902031447.rlib
collect2: error: ld returned 1 exit status
error: could not compile tikv-server (bin "tikv-server") due to 1 previous error
make: *** [Makefile:200: build] Error 101
这个提示比较明确是找不到undefined symbol: rocksdb::encryption::NewKeyManagedEncryptedEnv(rocksdb::Env*, std::shared_ptrrocksdb::encryption::KeyManager&)
,这个函数。
同样是丢给deepseek,给出的方法是
链接器无法找到符号 NewKeyManagedEncryptedEnv 表明 RocksDB 未正确编译加密模块。
TiKV 的加密功能需要 RocksDB 编译时启用 LIBROCKSDB_ENABLE_ENC=1 标志。
建议设置环境变量
export LIBROCKSDB_ENABLE_ENC=1
设置好,需要make clean,再make build,不make clean直接make build还是会报错的。
编译完成后是这个样子的,有些警告,但不影响编译成功。
进入target/x86_64-unknown-linux-gnu/debug目录下就能看到我们的编译成果。
主要是tikv-ctl和tikv-server,这两个。
用./tikv-server --version查看版本信息,如上所示。
大功告成。
总结
1,在windows系统下使用linux的相关工具,WSL提供了很大的便利。正在渐渐成为主流选择。
2,编译tikv的过程有很多工具的版本和库在原始的文档上写的不清楚,
https://github.com/tikv/tikv/blob/master/CONTRIBUTING.md
当然这是没问题,因为在不同linux发行版和版本下,这些要求都不一样,没法继续细化,真细化下去这个文档就会长的离谱。没有必要。但这些问题对一个从来没有接触过编译的人,确实存在障碍。
在WSL的ubuntu24下,编译环境被严格限定,我就能特别细化一下这部分。希望对初学者有所帮助。
3,AI时代善用deepseek这类工具,这类工具解决编译错误的效率非常高。只是AI如果给出让你修改代码类的提示,你要慎重,这不太可能是正确答案。回头看,通过调整环境变量来完成编译是最佳选择。
整体看tikv的编译难度并不高。有机会,大家可以踊跃尝试。