OB比赛记录
当时比赛期间因为太赶了,没来得及写,比完初赛论文又快截稿了。过年期间终于得闲,也算是重温一下OB比赛的心路。
[比赛介绍]{https://oceanbase.github.io/miniob/game/introduction/}
[代码仓库]{https://github.com/oceanbase/miniob}
架构
请求处理链路
一条 SQL 请求在 observer 中的标准处理路径如下:
Communicator(read_event) -> SessionEvent -> SqlTaskHandler::handle_sql ->
QueryCacheStage -> ParseStage -> ResolveStage -> OptimizeStage -> ExecuteStage -> Communicator(write_result)
说明:
QueryCacheStage当前实现为透传(默认返回成功,不做实质缓存处理)。- 对需要物理计划的语句,
ExecuteStage负责把物理算子交给SqlResult,实际执行由回包阶段调用SqlResult::open/next_tuple驱动。
Session 层说明
每次Client和Observer连接,都用一个session管理。
Session 维护的上下文:
- 当前选中的数据库(Db)。
- 唯一事务指针(Trx,按需创建)。
- 记录当前请求(
current_request)。 - 保存 SQL 运行参数(例如
execution_mode、hash_join、use_cascade、sql_debug)。
补充说明:
DefaultHandler属于全局对象,在系统init阶段创建,不属于 session 生命周期内对象。
对应代码文件:
src/observer/session/session.hsrc/observer/session/session.cppsrc/observer/net/server.cppsrc/observer/common/init.cppsrc/observer/storage/default/default_handler.hsrc/observer/storage/default/default_handler.cpp
Parser 层说明
Parser 层分为词法分析和语法分析两部分:
- Lexer:对应
lex_sql.l,负责把字符流切分为词法单元。 - Parser:对应
yacc_sql.y,负责将词法单元按语法规则归约组合成AST树。
Parser 输出对象为 ParsedSqlNode,作为后续 Resolve 阶段的输入。
对应代码文件:
src/observer/sql/parser/lex_sql.lsrc/observer/sql/parser/yacc_sql.ysrc/observer/sql/parser/parse.cppsrc/observer/sql/parser/parse_defs.hsrc/observer/sql/parser/parse_stage.cpp
Resolve 层说明
ResolveStage 的职责是把 ParsedSqlNode 转换成语义化的 Stmt 对象(入口为 Stmt::create_stmt)。即语义解析。
表达式语义绑定由 ExpressionBinder 完成,通常发生在各类 Stmt::create(...) 过程中(如 SelectStmt、UpdateStmt、FilterStmt),用于完成字段解析、类型检查与表达式重写前的语义准备。
对应代码文件:
src/observer/sql/parser/resolve_stage.cppsrc/observer/sql/stmt/stmt.cppsrc/observer/sql/parser/expression_binder.hsrc/observer/sql/parser/expression_binder.cppsrc/observer/sql/stmt/select_stmt.cppsrc/observer/sql/stmt/update_stmt.cppsrc/observer/sql/stmt/filter_stmt.cpp
Optimizer 层说明
从stmt生成不同的query plan(查询计划)并优化执行计划,后面会以此找到对应的operator(算子)。核心流程为:
Stmt -> Logical Plan -> Rewrite -> Physical Plan
语句类别与优化路径:
- DDL / 命令类语句:通常不生成物理计划,执行时走
CommandExecutor。 - DML / DQL 语句:通常生成逻辑计划与物理计划后执行。
当前实现特性:
- 支持 rewrite 迭代执行,直到计划不再变化。
- 支持常规物理计划生成与 cascade 路径(由 session 开关控制)。
- 支持 tuple/chunk 两种执行模式(由 session 变量控制并在优化阶段落地)。
对应代码文件:
src/observer/sql/optimizer/optimize_stage.hsrc/observer/sql/optimizer/optimize_stage.cppsrc/observer/sql/optimizer/logical_plan_generator.hsrc/observer/sql/optimizer/logical_plan_generator.cppsrc/observer/sql/optimizer/physical_plan_generator.hsrc/observer/sql/optimizer/physical_plan_generator.cpp
Execute 层说明
Execute 层根据是否存在物理计划分流:
- 存在 physical operator:将算子注册到
SqlResult,由输出阶段逐步执行并产出结果。 - 不存在 physical operator 但存在
Stmt:按语句类型走CommandExecutor(如 DDL、SET、事务控制语句等)。
对应代码文件:
src/observer/sql/executor/execute_stage.hsrc/observer/sql/executor/execute_stage.cppsrc/observer/sql/executor/command_executor.hsrc/observer/sql/executor/command_executor.cppsrc/observer/sql/executor/sql_result.hsrc/observer/sql/executor/sql_result.cpp
Storage 层说明
存储层的metadata和engine需要额外注意。每次操作都要注意元数据的存取或者更新,同样,最终交互的“契约”(CRUD)是在执行引擎中实现的。
存储侧主要分层如下:
DefaultHandler(全局入口)
-> Db(数据库生命周期、表/视图管理、buffer pool、log handler、trx kit)
-> Table(表级逻辑对象,持有 unique_ptr<TableEngine>)
-> TableEngine(具体存储实现:HeapTableEngine / LsmTableEngine)
-> Record / Index(记录与索引读写)
-> BufferPool + Log/WAL + DoubleWrite(页缓存与持久化保障)
开发关注点:
- 当前代码同时支持 heap 与 lsm 两种表引擎,lsm还未实现。
Db层包含恢复逻辑(recover),属于启动路径关键部分。Db不仅管理 table,也管理 view 的创建、删除和查找。
对应代码文件:
src/observer/storage/default/default_handler.hsrc/observer/storage/default/default_handler.cppsrc/observer/storage/db/db.hsrc/observer/storage/db/db.cppsrc/observer/storage/table/table.hsrc/observer/storage/table/table.cppsrc/observer/storage/table/table_engine.hsrc/observer/storage/table/heap_table_engine.hsrc/observer/storage/table/heap_table_engine.cppsrc/observer/storage/table/lsm_table_engine.hsrc/observer/storage/table/lsm_table_engine.cppsrc/observer/storage/buffer/disk_buffer_pool.hsrc/observer/storage/clog/log_handler.h
事务(Trx)说明
事务对象与 session 绑定,按需创建,并下传到 record 级别的读写路径。
当前可选事务模型:
vacuousmvcclsm
具体模式由启动参数选择,并通过 TrxKit 抽象创建和管理。
对应代码文件:
src/observer/storage/trx/trx.hsrc/observer/storage/trx/trx.cppsrc/observer/storage/trx/vacuous_trx.hsrc/observer/storage/trx/vacuous_trx.cppsrc/observer/storage/trx/mvcc_trx.hsrc/observer/storage/trx/mvcc_trx.cppsrc/observer/storage/trx/lsm_mvcc_trx.hsrc/observer/storage/trx/lsm_mvcc_trx.cpp
索引(Index)说明
索引元信息由 IndexMeta 描述,具体索引结构由 table engine 与索引实现类协同维护。
当前索引能力包括:
- B+ 树索引。
- 其它扩展索引实现(例如全文相关实现)。
B+ 树常用接口:
insert_entrydelete_entryget_entrycreate_scanner
对应代码文件:
src/observer/storage/index/index.hsrc/observer/storage/index/index.cppsrc/observer/storage/index/index_meta.hsrc/observer/storage/index/index_meta.cppsrc/observer/storage/index/bplus_tree.hsrc/observer/storage/index/bplus_tree.cppsrc/observer/storage/index/bplus_tree_index.hsrc/observer/storage/index/bplus_tree_index.cppsrc/observer/storage/index/full_text_index.h