MiniOB 完整导读不到 10 万行代码把 B 树索引、事务和 SQL 执行链路一次讲透【免费下载链接】miniobMiniOB is a compact database that assists developers in understanding the fundamental workings of a database.项目地址: https://gitcode.com/GitHub_Trending/mi/miniobMiniOB 是 OceanBase 团队做的一个教学用关系型数据库用 C 写成支持建表、插数、查询、B 树索引和 MVCC 事务。它把真实数据库里最核心的模块都做了一遍但刻意砍掉了安全、高可用这些干扰项代码量控制在 10 万行以内。读完本文你会知道怎么把它编译跑起来、一条 SQL 进去之后内部走了哪几步、B 树索引的源码在哪里改最后还有一个一小时内能完成的小练习。 先跑起来一条命令完成构建环境要求写在 docs/docs/how_to_build.md 里cmake 3.13、GCC 11 或 Clang 14 以上、flex 和 bison都是常见版本Linux 和 macOS 都适用。git clone https://gitcode.com/GitHub_Trending/mi/miniob cd miniob bash build.sh init bash build.sh cd build_debug ./bin/observer -f ../etc/observer.ini -P clibuild.sh init只跑一次把第三方依赖装到deps/3rd/usr/local下后面的build.sh默认编译 debug 版。启动参数-P cli表示直接交互模式不用另开客户端这是新手最省事的姿势。进去之后直接敲create table t1 (a int, b int);再select * from t1;看到空结果集说明服务已经正常。想体验客户端模式的话用-p 6789启动 observer另开终端跑./bin/obclient -p 6789具体参数见 docs/docs/how_to_run.md。️ 跟一条 SQL 走到黑执行链路拆成四步你敲下的select * from t1 where a 1;不会一步到位它要在系统里接力传递。以一条带 where 条件的 select 为例链路是这样的收包与调度。网络模块收到请求交给 TaskHandler它会为这条 SQL 建一个事件对象并绑定当前会话。对应代码在 src/observer/net/。解析。Flex Bison 做词法和语法分析把 SQL 文本变成抽象语法树AST。词法规格在 src/observer/sql/parser/ 里的.l和.y文件里想搞清楚语法到底怎么定义的翻这两个文件比看任何博客都快。语义分析。Resolver 遍历 AST检查表和列是否存在、类型是否匹配然后生成内部的 Stmt 对象比如 SelectStmt代码在 src/observer/sql/stmt/。优化与执行。Optimizer 根据规则调整执行计划Executor 按算子树执行——表扫描、条件过滤这些都在 src/observer/sql/operator/ 下一个算子一个文件结构非常清晰。这四个阶段由 SessionStage 用责任链模式串起来入口在 src/observer/session/session_stage.cpp顺着handle_request一路往下跟链路自然就出来了。 拆一个模块B 树索引怎么把键变成磁盘页B 树是 MiniOB 的默认索引结构也是数据库里最经典的磁盘数据结构。它要解决的问题是表数据动辄几百兆凭什么一次查询只读几次磁盘就能定位到一行答案藏在页的设计里。每个结点就是一个固定大小的 page叶结点按顺序存放索引列值 RIDRID 指向数据行在磁盘上的位置并且用prev_brother/next_brother把相邻叶结点串成链表所以等值查询和范围查询都走同一套叶子路径。内部结点不存数据只存键 子结点 page 号查询从根页出发逐层往下每层只读一个 page。插入时叶结点满了就分裂新建右兄弟、键值对对半搬、把新结点最小键上提如果一路向上都满就新建根页让树长高。删除方向则相反结点键值对少于一半时触发兄弟合并或重构。设计文档 docs/docs/design/miniob-bplus-tree.md 里每一步都配了图实现代码在 src/observer/storage/index/主文件是bplus_tree.cpp。另外src/oblsm/下还有一套完整的 LSM-Tree 引擎memtable sstable compaction想换一种索引思路可以从那边走进去。️ 一个小练习一小时内读懂 B 树的插入路径任务是跑通 B 树单元测试再顺着一次插入把源码跟一遍不用写新代码。确认已经用bash build.sh编译过单测目标默认开启CMake 里的WITH_UNIT_TESTS。在build_debug目录下执行ctest -R bplus_tree会运行bplus_tree_test它覆盖插入、删除、页分裂和日志恢复等场景。测试入口在 unittest/observer/bplus_tree_test.cpp看test_insert函数怎么构造 RID 再往树里灌数据。打开 src/observer/storage/index/bplus_tree.cpp找到插入和分裂相关的函数对照设计文档里的分裂图确认新结点最小键上提到父结点这一步在代码里的位置。做完这一轮你对索引在磁盘上长什么样应该就有具体画面了。想继续加难度可以去 docs/docs/db_course_lab/ 看官方实验题lab1 到 lab4 分别是 LSM 存储、查询引擎、事务引擎和性能测试。❓ 踩坑 FAQ问跑build.sh报build.sh: line 2: $\r: command not found典型的 Windows 换行符污染脚本里的 CRLF 被带进来了。先执行git config --global core.autocrlf false再用git checkout -- .把工作区文件重写一遍重新构建即可。问启动 observer 提示找不到动态链接库依赖默认装在/usr/local下而它不一定在你的动态库搜索路径里。把export LD_LIBRARY_PATH/usr/local/lib64:$LD_LIBRARY_PATH加进~/.bashrc然后source ~/.bashrc重启程序。问想打断点看某条 SQL 的执行入口在哪调试方法写在 docs/docs/dev-env/miniob-how-to-debug.md。最快的一条路是gdb -p \pidof observer挂上已启动的服务然后对do_select或Table::scan_record 下断点单步就能看见 select 从上层算子一路落到存储层的过程。MiniOB 的代码结构对读源码非常友好一层目录对应一个模块一个文件基本对应一个算子或一类页结构配合设计文档可以按图索骥。建议的节奏是先让服务跑起来再挑本文这条 SQL 链路跟一遍最后用 B 树单测收口内核的主要骨架就摸清了。资源索引官方文档目录docs/docs/架构总览在 docs/docs/design/miniob-architecture.md服务端源码入口src/observer/main.cppSQL 与存储分别在 src/observer/sql/ 和 src/observer/storage/单元测试unittest/集成测试test/integration_test/【免费下载链接】miniobMiniOB is a compact database that assists developers in understanding the fundamental workings of a database.项目地址: https://gitcode.com/GitHub_Trending/mi/miniob创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考