Skip to content
This repository has been archived by the owner on Mar 26, 2024. It is now read-only.

Latest commit

 

History

History
294 lines (220 loc) · 15.3 KB

代码文档.md

File metadata and controls

294 lines (220 loc) · 15.3 KB

1.代码框架

1.1 文件列表

路径 重要类 说明
common Init 初始化服务器配置
event SessionEvent、SqlEvent 处理SQL请求、SQL调试信息
net Server 网络模块,负责客户端与服务端通信
session SessionStage 创建Session窗口(每次输入SQL语句时创建)
sql/parser ParseStage、ResolveStage SQL解析处理阶段,将SQL解析为语法树和Stmt语义
sql/stmt Stmt 定义各种SQL语句的Stmt语义
sql/operator - 实现各种查询计划
sql/expr Expression、Tuple 定义表达式类型、表示一行数据
sql/optimizer OptimizeStage 查询优化阶段
sql/executor ExecuteStage SQL执行阶段,实现了各种SQL语句的Executor
sql/plan_cache PlanCacheStage 计划缓存阶段,本项目未实现
sql/query_cache QueryCacheStage 查询缓存阶段,本项目未实现
storage/db Db 数据库实现类
storage/table Table 数据表实现类
storage/record Record 数据表中的记录类
storage/field Field、FieldMeta 数据表中的字段类
storage/index Index、B+Tree 索引类、B+树实现
storage/trx - 事务类
storage/clog - 定义事务操作的类型和日志文件的格式
storage/buffer Page、Frame、DiskBufferPool 定义页、页帧、缓冲池
storage/persist PersistHandler 数据持久化类,定义打开、删除等文件操作
storage/common MetaUtil 工具类,指定数据库文件的扩展名

1.2 枚举类

路径 说明
RC common/rc.h 函数返回码
CompOp sql/parser/parse_defs.h 描述比较运算符
SqlCommandFlag sql/parser/parse_defs.h SQL语句类型
ExprType sql/expr/expression.h 表达式类型
AttrType sql/parser/value.h 字段类型
StmtType sql/stmt/stmt.h Stmt语义类型
CLogType storage/clog/clog.h 事务日志类型

2.运行与调试

2.1 运行Miniob

  • 以监听TCP端口的方式启动

    • 运行服务端

      ./bin/observer -f ../etc/observer.ini -p 6789
    • 运行客户端

      ./bin/obclient -p 6789
  • 以监听unix socket的方式启动

    • 运行服务端

      ./bin/observer -f ../etc/observer.ini -s miniob.sock
    • 运行客户端

      ./bin/obclient -s miniob.sock
  • 以直接执行命令的方式启动

    • 单线程模式,可以直接在服务端输入命令,不需要客户端

      ./bin/observer -f ../etc/observer.ini -P cli

3. 模块详解

3.1 SQL语句执行流程

3.1.1 整体流程

函数 服务端
- main@src/observer/main.cpp 启动服务端(解析命令行参数、加载配置文件、初始化)
Server recv@src/observer/net/server.cpp 客户端输入SQL并回车后,Server接收客户端消息并创建SessionEvent
SessionStage handle_request@src/observer/session/session_stage.cpp 处理SessionEvent并创建SQLStageEvent
SessionStage handle_sql@src/observer/session/session_stage.cpp 执行各阶段的SQL处理
QueryCacheStage handle_request@src/observer/sql/query_cache/query_cache_stage.cpp 查询缓存
ParseStage handle_request@src/observer/sql/parser/parse_stage.cpp 解析SQL语句为ParsedSqlNode
ResolveStage handle_request@src/observer/sql/parser/resolve_stage.cpp 解析ParsedSqlNode为Stmt
分支操作 - 根据SQL语句是否进行查询计划分支操作
SessionStage handle_request@src/observer/session/session_stage.cpp 向客户端返回结果(打印SessionEvent中SqlResult属性的内容)

3.1.2 无需查询计划

函数 功能类
ExecuteStage handle_request@src/observer/sql/executor/execute_stage.cpp 调用CommandExecutor执行
CommandExecutor execute@src/observer/sql/executor/command_executor.cpp 根据StmtType分发执行
Executor - 调用db->调用table执行相关操作

3.1.3 需要查询计划

函数 功能类
OptimizeStage handle_request@src/observer/sql/optimizer/optimize_stage.cpp 创建查询计划,并进行优化(在select、insert、update、delete时使用)
ExecuteStage handle_request@src/observer/sql/executor/execute_stage.cpp 根据StmtType执行查询计划,将结果写入SessionEvent的SqlResult属性

3.2 查询计划

3.2.1 逻辑计划

  • 逻辑算子描述当前执行计划要做什么,比如从表中获取数据,过滤,投影,连接等

  • 属性列表

    属性 类型 说明
    type() LogicalOperatorType 指定算子类型,如从表中获取数据、过滤、投影、连接、插入、删除、查看执行计划、更新
    children List 子算子列表
    expressions_ List 子算子列表对应的表达式列表

3.2.2 物理计划

  • 物理算子描述如何执行当前计划,这是与逻辑算子不同之处

  • 算子是最小执行单位,是事务性的

  • Mniob采用流水线模型(火山模型)执行查询计划,即从根节点开始递归调用孩子结点的next()函数,逐行获取元组并由下至上进行相应的运算,直到处理完表中的所有元组,同时生成要返回的结果集字符串

  • 属性列表

    属性 类型 说明
    type() 返回PhysicalOperatorType 指定算子类型,如扫描表、扫描索引、嵌套连接、查看执行计划、过滤、投影、计算、删除等
    children List 子算子列表
    open() 参数为Trx 开始执行一个算子时需要开启事务
    next() - 逐行调用子算子的next(),获取其current_tuple(),
    close() - 关闭算子
    current_tuple() 返回Tuple 当前Tuple

4. 实验题目

4.1 必做题

4.1.1 题目列表

名称 分值 说明
basic 10 基本功能
drop-table 10 删除表
update 10 更新字段
date 10 日期字段
select-tables 10 多表查询
select-meta 10 表结构
aggregation-func 10 聚合函数

4.1.2 drop-table

假设表名为demo

  • 分析

    • 需要删除demo.table文件、demo.data文件和关联的索引文件

    • 由于具体执行阶段在CommandExecutor进行分发,因此需要实现DropTableExecutor

    • 相应地,需要实现DropTableStmt

  • 实现

    • 实现DropTableExecutor
      • db中实现delete_table接口
      • table中实现destroy接口
        • 删除Meta
        • 删除Data
        • 删除索引
        • 清空buffer pool
    • CommandExecutor增加对StmtType::DROP_TABLE的执行分支

4.1.3 update

  • 分析
    • 更新语句涉及修改数据库,可能会用到where语句,因此需要实现查询计划
  • 实现
    • 实现UpdateLogicalOperator、UpdatePhysicalOperator
    • 在LogicalPlanGenerator、PhysicalPlanGenerator中分别实现生成UpdateLogicalOperator、UpdatePhysicalOperator的逻辑
    • 实现UpdateStmt::create函数,从而实现Update语句的处理逻辑
      • 重写type
      • 检查参数合法性(表名、字段名不为空)
      • 检查表是否存在
      • 检查字段是否存在
    • 由于可能会用到where语句,因此需要在UpdateStmt中实现FilterStmt

4.1.4 date

要求:增加date字段。字段不会超过2038年2月,不会小于1970年1月1号

  • 分析

    • 在parser中添加对date关键字、date取值、date字段的词法语法定义
    • 对于insert/update语句,需要检查插入或更新的date字段值是否合法
    1. 对于select语句,需要检查where条件中出现的date值是否合法
  • 实现

    • 在lex中添加date的正则表达式,并在此处将字符串转换为date类型,如果字符串不合法,则该date值为0,便于后续判断
    • 在value.cpp中添加DATES的属性类型、date类型的构造函数、set_date、get_date、实现to_string、实现compare、在联合体中添加date字段date_value_
    • 在filter_stmt中添加对date为0的特判:select/update中检查date是否合法
    • 在insert_stmt中添加对date为0的特判:insert中检查date是否合法
    • 在B+树中添加对compare类型的比较(实际上由于Miniob底层代码逻辑缺陷,此处调用value.cpp中的compare方法实现为好,扩展性更强)

4.1.5 select-tables

  • 分析
    • 可以分解为三个操作:两张表分别针对要select的字段进行TableSelect算子、进行Join连接算子、根据where子句进行过滤算子
  • 实现
    • 与Update类似,需要在LogicalPlanGenerator、PhysicalPlanGenerator中分别实现生成select逻辑计划、select物理计划的逻辑,此处无需单独实现SelectLogicalOperator、SelectPhyicalOperator,利用已有算子即可实现

4.1.6 aggregation-func

要求:实现max/min/count/avg函数;包含聚合字段时,只会出现聚合字段;聚合函数中的参数不会是表达式,比如age+1

  • 分析

    • 首先在lex和yacc中添加各聚合函数的token

    • select的语法解析树中,select_attrs需要改为select_exprs,即引入聚合函数后,select的内容由字段列表变为表达式列表

    • 在yacc中定义select_expr、select_expr_list、select_exprs、aggr_func

      • select_expr可以是rel_attr、也可以是aggr_func
      • select_expr_list参照attr_list
      • select_exprs可以是select_expr_list,也可以是*表示所有字段
      • aggr_func由aggr_fun_name和select_attr组成
    • 将yacc中定义的语义变量转换为相应数据结构

      • select_expr >> SelectExprNode(指定表达式类型SelectExprType、字段名/聚合函数)
      • aggr_func >> AggrFuncNode(指定聚合函数类型AggrFuncType、字段列表)
      • 修改SelectSqlNode的属性(去除attributes,添加select_exprs)
    • 修改SelectStmt的create逻辑

      • SelectStmt中删除原属性query_fields,添加表达式Expression列表query_exprs
      • 遍历SelectSqlNode中的select_exprs
        • 如果是聚合函数,那么根据SelectExprType的arrgfunc属性创建AggrStmt并转换为Expression
        • 如果是字段
          • 表名为空,列属性为*,添加所有表的所有列
          • 表名为空,列属性不为*,默认为第一个表,如果存在多个表报错
          • 表名不为空
            • 表名为*,属性不为*,不合法
            • 表名不为*,属性为*,添加该表的所有列(判断表是否存在)
            • 表名不为*,属性不为*,添加该列(判断表和列是否存在)
    • 在表达式Expression中添加AggrExpr表示聚合函数表达式

      • 添加ExprType
      • 定义各种聚合函数的操作
    • 修改select逻辑计划、select物理计划的逻辑

      • 实现AggrLogicalOperator、AggrPhysicalOperator

4.2 选做题

4.2.1 题目列表

名称 分值 说明
insert 10 插入多条数据
unique 10 唯一性索引
null 10 空值
order-by 10 排序
simple-sub-query 10 简单子查询
complex-sub-query 20 复杂子查询
group-by 20 分组
join-tables 20 连接查询
expression 20 表达式
text 20 TEXT字段
multi-index 20 多索引

4.2.2 insert

要求:支持插入多条数据,且要同时失败或成功

  • 分析
    • 修改parser模块,使其支持插入多条数据
    • 修改InsertStmt
    • 修改InsertLogicalOperator、InsertPhysicalOperator

4.2.3 null

4.2.4 unique

4.2.5 join-tables

4.2.6 group-by

4.2.7 order-by