MiniOB 项目调试指南:从日志打印到 GDB 高级调试

MiniOB 项目调试指南:从日志打印到 GDB 高级调试

miniob MiniOB is a compact database that assists developers in understanding the fundamental workings of a database. miniob 项目地址: https://gitcode.com/gh_mirrors/mi/miniob

前言

在数据库系统开发过程中,调试是必不可少的环节。本文将详细介绍如何对 MiniOB 数据库系统进行高效调试,包括日志调试和 GDB 调试两种主要方法。

一、MiniOB 关键代码结构分析

在开始调试前,我们需要先了解 MiniOB 的核心代码结构,这对后续调试工作至关重要。

1.1 关键数据结构

MiniOB 的核心数据结构主要集中在以下几个文件中:

// SQL 解析相关结构
parse_def.h:
    struct Selects;      // 查询语句结构
    struct CreateTable;  // 建表语句结构
    struct DropTable;    // 删表语句结构
    enum SqlCommandFlag; // SQL 命令枚举
    union Queries;      // 各类 DML 和 DDL 操作的联合体

// 表相关结构
table.h
    class Table;        // 表基类

// 数据库相关结构
db.h
    class Db;           // 数据库类

1.2 核心接口

MiniOB 的主要功能接口分布在以下模块中:

// SQL 解析入口
RC parse(const char *st, Query *sqln);

// 执行阶段关键接口
ExecuteStage::handle_request
ExecuteStage::do_select

// 存储引擎接口
DefaultStorageStage::handle_event
DefaultHandler::create_index
DefaultHandler::insert_record
DefaultHandler::delete_record
DefaultHandler::update_record

// 数据库操作接口
Db::create_table
Db::find_table

// 表操作接口
Table::create
Table::scan_record
Table::insert_record
Table::update_record
Table::delete_record
Table::create_index

二、日志调试方法

日志调试是最基础也是最常用的调试手段,MiniOB 提供了完善的日志系统。

2.1 日志接口

MiniOB 的日志系统提供了多级别日志输出:

// deps/common/log/log.h 中定义的日志级别
#define LOG_PANIC(fmt, ...)  // 严重错误
#define LOG_ERROR(fmt, ...)  // 错误信息
#define LOG_WARN(fmt, ...)   // 警告信息
#define LOG_INFO(fmt, ...)   // 普通信息
#define LOG_DEBUG(fmt, ...)  // 调试信息
#define LOG_TRACE(fmt, ...)  // 跟踪信息

2.2 日志配置

日志行为可以通过 observer.ini 配置文件进行调整:

[log]
LOG_FILE_NAME = observer.log
LOG_FILE_LEVEL = 5    # 日志文件记录级别(0-5)
LOG_CONSOLE_LEVEL = 1 # 控制台输出级别(0-5)

日志级别说明:

  • 0: PANIC
  • 1: ERROR
  • 2: WARN
  • 3: INFO
  • 4: DEBUG
  • 5: TRACE

2.3 调用栈追踪

MiniOB 提供了 lbt() 函数用于获取当前调用栈信息,这在调试复杂问题时非常有用:

LOG_DEBUG("debug lock %p, lbt=%s", &lock_, lbt());

日志输出示例:

unlock@mutex.cpp:273] >> debug unlock 0xffffa40fe8c0, lbt=0x4589c 0x5517f8 0x5329e0...

可以使用 addr2line 工具解析地址信息:

addr2line -pCfe ./bin/observer [地址列表]

三、GDB 调试实战

GDB 是 Linux 下最强大的调试工具,下面介绍在 MiniOB 开发中的 GDB 使用技巧。

3.1 基本调试流程

  1. 附加到进程

    gdb -p `pidof observer`
    
  2. 设置断点

    (gdb) break do_select
    (gdb) break Table::scan_record
    
  3. 查看断点信息

    (gdb) info breakpoints
    
  4. 继续执行

    (gdb) continue
    

3.2 高级调试技巧

  1. 单步调试

    • next (或 n): 单步执行,不进入函数
    • step (或 s): 单步执行,进入函数
  2. 变量查看

    (gdb) print variable_name
    
  3. 监视变量

    (gdb) watch variable_name
    
  4. 函数调用栈

    (gdb) backtrace
    
  5. 结束当前函数

    (gdb) finish
    

3.3 调试示例

调试 SELECT 查询执行流程:

# 设置断点
(gdb) break ExecuteStage::do_select
(gdb) break Table::scan_record

# 继续执行
(gdb) continue

# 触发断点后单步执行
(gdb) next
(gdb) step

# 查看变量值
(gdb) print tuple_set

# 监视返回值
(gdb) watch -l rc

四、Visual Studio Code 集成调试

对于习惯使用 IDE 的开发者,VSCode 提供了良好的调试支持。

4.1 调试配置

MiniOB 项目已经预置了 .vscode/launch.json 配置文件,主要包含:

  • type: 调试器类型(lldb 或 cppdbg)
  • program: 要调试的程序路径(observer)
  • args: 命令行参数
  • cwd: 工作目录

4.2 任务配置

.vscode/tasks.json 中预置了构建任务,例如:

{
    "label": "build_debug",
    "type": "shell",
    "command": "bash build.sh debug",
    "group": {
        "kind": "build",
        "isDefault": true
    }
}

4.3 调试流程

  1. 使用 Ctrl+Shift+B 构建项目
  2. 切换到调试视图
  3. 选择调试配置(Debug 或 LLDB)
  4. 点击启动调试按钮

五、调试建议

  1. 从高层开始:先理解整体流程,再深入细节
  2. 合理使用断点:在关键接口处设置断点
  3. 结合日志和调试器:日志看流程,调试器查细节
  4. 关注返回值:数据库操作中返回值(RC)非常重要
  5. 理解调用栈:遇到问题时先查看调用栈

通过以上方法,开发者可以高效地定位和解决 MiniOB 开发过程中遇到的各种问题。

miniob MiniOB is a compact database that assists developers in understanding the fundamental workings of a database. miniob 项目地址: https://gitcode.com/gh_mirrors/mi/miniob

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韦韬韧Hope

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值