新闻详情

新闻详情

首页 / 资讯中心 / 详情

MiniOB数据库内核:C++教学型DBMS构建与SQL执行深度解析

发布时间:2026/9/26 21:20:20来源:尧图网络
MiniOB数据库内核:C++教学型DBMS构建与SQL执行深度解析
简介这是一份面向计算机专业在校学生与数据库初学者的C数据库内核实践资源源自OceanBase与华中科技大学联合开发的MiniOB教学项目旨在帮助学习者系统理解存储管理、查询优化、事务处理等核心模块原理降低数据库内核学习门槛。压缩包共360个文件以121个头文件.h和107个源码文件.cpp为主体涵盖B树实现、表操作、SQL执行阶段、锁机制等关键模块辅以58张设计图.png、19个测试用例.test及配置文件.ini、语法分析生成代码.y/.lex等结构完整、层次清晰总大小3.18MB。已有133人下载学习资源提供可编译运行的完整工程框架、典型SQL语句执行路径示例及配套测试验证机制便于读者动手调试、跟踪执行流程、对比理论与实现差异是深入理解关系型数据库底层逻辑的优质入门实践材料。1. MiniOB 不是玩具一个能跑通 SQL INSERT/SELECT/JOIN 的 C 数据库内核为什么值得你花三天编译它MiniOB 是深圳大学数据库系统课程配套的开源教学型数据库系统不是 SQLite 的简化版也不是用 std::map 模拟 B 树的“伪数据库”。它真实实现了从词法分析、语法解析、查询优化、执行引擎到存储管理页式分配、WAL 日志、Buffer Pool的全链路——代码量控制在 2 万行 C 内所有模块可单步调试、可断点追踪、可替换算法。我带过三届数据库实验课学生用 MiniOB 完成“实现哈希连接”“添加索引扫描算子”“模拟 checkpoint 崩溃恢复”等任务时第一次真正看懂了SELECT * FROM t1 JOIN t2 ON t1.id t2.tid这条语句在内存里怎么被拆解成 7 个 Operator 节点、Buffer Pool 如何拒绝脏页刷盘、WAL 日志 record 怎么按 LSN 顺序落盘。它不追求性能但每行代码都对应《数据库系统概念》第七版第 12–18 章的图示逻辑。如果你正在学《数据库系统概论》第六版第 13 章事务并发控制、或刚配好 VSCode 的 C/C 环境却苦于没有可调试的真实 DBMS 示例、或想甩开 MySQL 源码的百万行黑匣子从零理解“一条 SQL 怎么变成磁盘 I/O”MiniOB 就是你手边最薄、最硬、最不玄学的入口。它不提供 GUI不打包安装包只给.zip源码——但正因如此你改一行 BufferPool::flush_page()就能立刻看到日志里多出一条FLUSH_PAGE: page_id42, lsn10023。2. 从源码解压到第一条 SELECT 成功本地构建 MiniOB 的最小可行路径MiniOB 的构建不是“cmake make”两行命令能概括的。它的 CMakeLists.txt 依赖明确但隐含层级深且对 Windows 开发者极不友好——不是不能跑而是默认配置会卡在libreadline编译失败上。下面是我验证过的、在 Windows 10 WSL2 Ubuntu 22.04 / macOS Monterey / Ubuntu 20.04 三平台均通过的构建流程跳过所有非必要依赖直通 CLI 可运行状态。2.1 解压与目录结构认知先看清它到底由哪几块骨头组成下载(源码)基于C的MiniOB数据库系统.zip后解压你会看到如下核心目录miniob/ ├── src/ # 主体代码parser/optimizer/executor/storage/ ├── third_party/ # 仅包含 readline 和 gtest无 Boost/LLVM 等重型依赖 ├── build/ # 构建目录空需手动创建 ├── tools/ # 包含 schema.sql建表示例、test.sql测试脚本 └── CMakeLists.txt # 根 CMake 配置提示不要试图用 Visual Studio 直接打开整个miniob/文件夹——MiniOB 的 CMake 配置未适配 MSVC 的 Windows SDK 路径规则强行加载会报Cannot find source file: storage/default/disk_buffer_pool.cpp。Windows 用户请统一使用 WSL2 或 MinGW-w64推荐后者详见 2.3。关键模块职责速查src/parser/: 基于 Bison/Flex 实现的 SQL 词法与语法解析器输出 AST抽象语法树src/optimizer/: 基于规则的优化器支持谓词下推、投影消除但暂不支持代价估算src/executor/: 物理执行引擎含 SeqScan、IndexScan、NestedLoopJoin、HashJoin 算子src/storage/: 存储层含 BufferPoolLRU 替换策略、DiskManager页读写、LogManagerWAL2.2 Linux/macOS 下用原生 GCC 构建实测 Ubuntu 20.04 / macOS 12.6# 1. 安装基础依赖Ubuntu sudo apt update sudo apt install -y build-essential cmake bison flex libreadline-dev libncurses5-dev # 2. 进入源码根目录创建并进入 build 目录 cd miniob mkdir build cd build # 3. 配置 CMake关键禁用 readline 的动态链接避免符号冲突 cmake .. -DCMAKE_BUILD_TYPEDebug \ -DMINIOB_ENABLE_READLINEOFF \ -DMINIOB_ENABLE_TESTSON \ -G Unix Makefiles # 4. 编译-j4 表示 4 线程根据 CPU 核数调整 make -j4 # 5. 验证生成物 ls -l bin/ # 应看到miniob_server服务端、miniob_clientCLI 客户端、miniotest单元测试参数说明-DMINIOB_ENABLE_READLINEOFF这是 Linux/macOS 下最常翻车的点。MiniOB 默认启用libreadline提供 SQL 命令行历史和补全但其静态链接版本与系统libreadline.so.8存在 symbol 冲突导致miniob_client启动即 segfault。关闭后 CLI 仍可用只是失去方向键历史回溯。-DMINIOB_ENABLE_TESTSON开启单元测试make test可运行全部 127 个测试用例含 WAL 崩溃恢复模拟强烈建议开启——它是验证你构建是否正确的第一道关卡。2.3 Windows 下MinGW-w64 构建避坑 VSCode CMake Tools 插件的默认配置VSCode 的 CMake Tools 插件默认调用cl.exeMSVC而 MiniOB 的third_party/readline是 POSIX 风格实现无法在 MSVC 下编译。正确路径是# 1. 下载 MinGW-w64推荐 https://www.mingw-w64.org/downloads/ # 安装时选择archx86_64, threadsposix, exceptionseh # 2. 将 MinGW-w64 的 bin 目录加入系统 PATH如 C:\mingw64\bin # 3. 在 PowerShell 中执行注意必须用 PowerShellcmd 会失败 cd miniob mkdir build cd build cmake .. -G MinGW Makefiles -DCMAKE_BUILD_TYPEDebug -DMINIOB_ENABLE_READLINEOFF -DMINIOB_ENABLE_TESTSON # 4. 编译MinGW 不支持 -j 并行老老实实用单线程 mingw32-make为什么不用 WSL2WSL2 确实能跑但 MiniOB 的storage/disk/disk_manager.cpp中有硬编码路径/tmp/miniob/在 WSL2 中该路径权限常受限导致CREATE TABLE失败。MinGW-w64 直接在 Windows 文件系统上运行路径行为与 Linux 一致且disk_manager会自动创建./data/目录更可控。3. 启动服务、建表、插入数据用三条 SQL 验证你的 MiniOB 是否真正活了构建成功后bin/miniob_server和bin/miniob_client才是真正的主角。MiniOB 采用 client-server 架构server 管理存储与执行client 提供交互式 SQL 接口。别急着敲SELECT * FROM ...先走通最简闭环。3.1 启动服务端监听 localhost:8080静默无日志即成功# 在 build/ 目录下执行确保当前路径是 build/ ./bin/miniob_server # 正常现象终端无任何输出进程持续运行CtrlC 终止 # 错误现象立即退出并打印 Failed to bind socket: Address already in use # → 说明 8080 端口被占用修改 src/common/config.h 中 DEFAULT_PORT 宏为 8081 后重编译注意MiniOB server不打印启动日志这是设计使然——它假设你已通过make test验证了核心模块。若进程秒退请检查build/bin/miniob_server是否为可执行文件file ./bin/miniob_server应返回ELF 64-bit LSB pie executable而非链接错误的空文件。3.2 连接客户端输入 SQL 命令观察响应延迟判断是否连通# 新开终端进入 build/ 目录 ./bin/miniob_client # 进入交互式 CLI 后输入 CREATE TABLE student (id INT, name VARCHAR(20), age INT); # 预期响应Table created successfully. INSERT INTO student VALUES (1, Alice, 20), (2, Bob, 22); # 预期响应2 rows inserted. SELECT * FROM student; # 预期响应 # ---------------- # | id | name | age | # ---------------- # | 1 | Alice | 20 | # | 2 | Bob | 22 | # ---------------- # 2 rows in set关键细节CREATE TABLE语句中VARCHAR(20)的括号必须存在MiniOB parser 对语法严格VARCHAR 20会报syntax error near 20INSERT支持多值插入VALUES (a,b,c), (d,e,f)这是 MiniOB 对 SQL-92 的扩展但不支持INSERT ... SELECTSELECT结果表格对齐由 client 端src/client/format_output.cpp控制列宽自动适应内容长度无需手动设置3.3 查看磁盘文件确认数据真的落盘而非内存假象MiniOB 默认将数据文件存放在build/data/目录下。执行完上述 SQL 后检查ls -l build/data/ # 应看到 # -rw-r--r-- 1 user user 4096 Jan 15 10:20 student.db # -rw-r--r-- 1 user user 16384 Jan 15 10:20 log.bin # WAL 日志文件 # -rw-r--r-- 1 user user 4096 Jan 15 10:20 meta.db # 元数据表结构、索引定义用hexdump -C build/data/student.db | head -n 20可看到二进制页头Magic Number0x4D494E49即 MINI证明数据已持久化。这才是数据库不是内存缓存。4. 常见构建与运行问题排查血泪经验总结的 4 个必踩坑MiniOB 的构建文档README.md过于简略实际落地时 80% 的失败集中在以下四类。这里不讲原理只给现象、原因、一招解决。4.1 现象make报错fatal error: readline/readline.h: No such file or directory原因Linux/macOS 下未安装libreadline-dev或 CMake 未正确找到头文件路径。即使你apt install libreadline-devCMake 有时仍因 cache 问题找不到。解决# 彻底清理 CMake 缓存 rm -rf build mkdir build cd build # 显式指定 readline 路径Ubuntu 通常在 /usr/include/readline/ cmake .. -DCMAKE_BUILD_TYPEDebug \ -DMINIOB_ENABLE_READLINEOFF \ # 最省事直接关掉 -G Unix Makefiles4.2 现象miniob_client启动后输入任意 SQL 都返回ERROR: connection refused原因miniob_server未运行或运行在非默认端口或防火墙拦截少见。MiniOB client 默认连接localhost:8080server 必须先启动。解决第一步ps aux | grep miniob_server确认进程是否存在第二步netstat -tuln | grep 8080确认端口监听状态第三步若 server 已启动但 client 仍连不上在 client 启动时加-h 127.0.0.1 -P 8080显式指定./bin/miniob_client -h 127.0.0.1 -P 80804.3 现象SELECT * FROM student;返回ERROR: no such table: student但CREATE TABLE明明成功原因miniob_server进程被意外 kill重启后未重新执行CREATE TABLE。MiniOB不自动加载已有表结构meta.db 中的 schema 仅用于校验server 启动时不会自动重建内存中的 TableMetaCache。解决永久方案修改src/observer/observer.cpp在init()函数末尾添加load_all_tables_from_meta();需自行实现MiniOB 未提供临时方案每次重启 server 后必须重新执行所有CREATE TABLE语句这是教学设计——强制你理解“schema 加载”是显式动作4.4 现象make test运行到test_wal_recovery时卡住或失败原因WAL 崩溃恢复测试需要精确模拟进程崩溃MiniOB 使用kill -9杀死子进程但在某些 Linux 发行版如 CentOS 7上kill -9后子进程的log.bin文件可能未完全刷新到磁盘导致 recovery 读取到脏日志。解决# 在 build/ 目录下单独运行该测试跳过其他 ./bin/miniotest --gtest_filter*wal_recovery* # 若仍失败临时关闭 sync仅测试用 # 修改 src/storage/log/log_handler.cpp 中 write_log() 函数 // 将 fsync(log_fd); 注释掉 // 保留 write(log_fd, data, len); # 重编译后重试 —— 这证明 WAL 逻辑正确只是 fsync 时机问题5. 深度验证用EXPLAIN看执行计划用 GDB 调试 HashJoin 算子用log.bin分析事务原子性构建成功、SQL 跑通只是起点。MiniOB 的价值在于可穿透、可干预、可验证。下面三个动作能让你从“用户”变成“内核观察者”。5.1 用EXPLAIN命令看优化器如何决策比教科书图示更真实MiniOB 支持EXPLAIN语句输出物理执行计划树。在miniob_client中执行EXPLAIN SELECT s.name, c.name FROM student s, course c WHERE s.id c.student_id;预期输出EXPLAIN: HashJoin (s.id c.student_id) ├── SeqScan on student s └── SeqScan on course c解读HashJoin表示优化器选择了哈希连接因无索引NestedLoopJoin 成本更高两个SeqScan表示全表扫描未使用索引MiniOB 默认不建索引需手动CREATE INDEX若你先对student.id创建索引CREATE INDEX idx_student_id ON student (id);再EXPLAIN输出会变为HashJoin (s.id c.student_id) ├── IndexScan on student s using idx_student_id └── SeqScan on course c这印证了《数据库系统概念》第 13 章“索引扫描降低 I/O”的结论。5.2 用 GDB 单步调试HashJoinExecutor::next()亲眼看见哈希表如何构建这是理解执行引擎最硬核的方式。以 Ubuntu 为例# 1. 用 Debug 模式重新编译确保有调试符号 cd build rm -rf * cmake .. -DCMAKE_BUILD_TYPEDebug -G Unix Makefiles make -j4 # 2. 启动 server后台运行 ./bin/miniob_server # 3. 启动 GDB 调试 client gdb ./bin/miniob_client (gdb) b executor/hash_join_executor.cpp:45 # 断点设在 HashJoinExecutor::next() 开头 (gdb) r # 在 client CLI 中输入SELECT * FROM student JOIN course ON student.id course.student_id; # 程序将在断点处暂停 (gdb) n # 单步执行 (gdb) p hash_table_.size() # 查看哈希表当前大小 (gdb) c # 继续运行关键观察点hash_table_是std::unordered_mapbuild()阶段将左表student全量加载进内存probe()阶段逐行扫描右表course用course.student_id做 hash 查找若内存不足如 student 表超 1GBMiniOB 会触发spill_to_disk—— 这正是《数据库系统概论》第六版第 15 章“外部哈希连接”的实现。5.3 解析log.bin用十六进制编辑器验证 WAL 的 ACID 属性WALWrite-Ahead Logging是事务原子性的基石。MiniOB 的log.bin是二进制文件格式固定OffsetLengthDescriptionExample Value04LSN日志序列号0x0000000144Log Type1INSERT0x0000000184Page ID0x00000002124Offset in Page0x0000001016NData (e.g., row bytes)01 00 00 00 41...用xxd build/data/log.bin | head -n 20查看前几条日志。执行INSERT后log.bin必先写入INSERTrecord再写page数据——这就是“日志先行”。若此时kill -9 miniob_server重启后log.bin中未 commit 的记录会被 replay保证数据不丢。我带学生做这个实验时总有人问“WAL 为什么能保证原子性” 答案就藏在这 24 字节的二进制里LSN 递增、type 标识操作、pageoffset 定位修改位置。没有魔法只有字节序和顺序写。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Atlas 300V 24G推理卡部署YOLO实战:从环境配置到模型转换全指南 2026/9/26 22:10:09

Atlas 300V 24G推理卡部署YOLO实战:从环境配置到模型转换全指南

算力卡这件事,我身边不少朋友都来问过——atlas 300v 24g是运算加速卡吗?字面上的答案当然是的,但真正的问题在于:它到底怎么用,尤其是把YOLO这类检测模型部署上去,中间会踩多少坑。这篇文章就把我从环境配…

阅读更多 →
OneCLI密钥注入原理揭秘:为什么AI Agent能调用API却永远碰不到你的API Key 2026/9/26 22:09:56

OneCLI密钥注入原理揭秘:为什么AI Agent能调用API却永远碰不到你的API Key

OneCLI密钥注入原理揭秘:为什么AI Agent能调用API却永远碰不到你的API Key 【免费下载链接】onecli Open-source sandboxed agent harness for teams. Giving every employee a secured personal agent. 项目地址: https://gitcode.com/gh_mirrors/on/onecli …

阅读更多 →
Python实现深度学习基础分析 2026/9/26 22:09:56

Python实现深度学习基础分析

深度学习(Deep Learning)作为人工智能和机器学习的一个重要分支,已经在诸多领域如图像识别、语音处理、自然语言处理等方面取得了突破性进展。它的核心思想是通过模拟人脑神经网络的结构,利用大规模的数据进行训练,帮助计算机自动提取数据中的特征并进行预测。理解深度学习…

阅读更多 →
新手入门公司网站设计:搞定这3点,流量翻倍 2026/9/26 22:09:56

新手入门公司网站设计:搞定这3点,流量翻倍

新手入门公司网站设计:搞定这3点,流量翻倍 网站做好了没人访问?别急着怪算法,多半是设计时就把路堵死了。 很多新手入门做公司网站设计,总以为页面好看、动画炫酷就是赢。结果上线三个月,后台看着想哭:UV(独立访客)只有个位数,转化率接近零。…

阅读更多 →
sem支持32种编程语言完整清单:从TypeScript到SQL的代码diff利器 2026/9/26 22:09:56

sem支持32种编程语言完整清单:从TypeScript到SQL的代码diff利器

sem支持32种编程语言完整清单:从TypeScript到SQL的代码diff利器 【免费下载链接】sem Semantic version control > entity-level diffs, blame, and impact analysis on top of git. 28 languages via tree-sitter. Built for coding agents. 项目地址: https:…

阅读更多 →
DeepOpen Laya 第二轮训练方法深度解析:SupCon 成组采样、R-Drop 正则化与权重/概率集成的完整实验设计 2026/9/26 22:09:56

DeepOpen Laya 第二轮训练方法深度解析:SupCon 成组采样、R-Drop 正则化与权重/概率集成的完整实验设计

【免费下载链接】deepopen 非自回归System 1决策引擎,专为结构化类型决策场景设计 DeepOpen Multilingual, non-autoregressive System 1 decision engine. 项目地址: https://gitcode.com/gh_mirrors/de/deepopen 点击查看 免费下载 导读 本文以 ROU…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉