关于 debugging
Turso 调试指南,涵盖 SQL 行为对比、日志、并发测试、确定性模拟和栈用量分析,面向排查项目数据库或运行时问题的开发者。
主要功能
- 01比较 SQLite 与 Turso 字节码
- 02使用 tursodb 检查 SQL 查询
- 03在测试中跟踪核心日志
- 04通过种子复现并发问题
- 05测量栈用量
适用场景
- 01定位 SQLite 兼容查询行为差异
- 02排查线程或存储相关故障
- 03检查深层嵌套表达式的栈限制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tursodatabase/ turso --skill debugging安装后在 Claude Code 中输入/debugging确认已加载。
详细介绍
调试指南
字节码对比流程
Turso 致力于兼容 SQLite。当行为出现差异时:
1. EXPLAIN query in sqlite3
2. EXPLAIN query in tursodb
3. Compare bytecode
├─ Different → bug in code generation
└─ Same but results differ → bug in VM or storage layer
示例
# SQLite
sqlite3 :memory: "EXPLAIN SELECT 1 + 1;"
# Turso
cargo run --bin tursodb :memory: "EXPLAIN SELECT 1 + 1;"
手动检查查询
cargo run --bin tursodb :memory: 'SELECT * FROM foo;'
cargo run --bin tursodb :memory: 'EXPLAIN SELECT * FROM foo;'
日志记录
# Trace core during tests
RUST_LOG=none,turso_core=trace make test
# Output goes to testing/test.log
# Warning: can be megabytes per test run
线程问题
使用 ThreadSanitizer 进行压力测试:
rustup toolchain install nightly
rustup override set nightly
cargo run -Zbuild-std --target x86_64-unknown-linux-gnu \
-p turso_stress -- --vfs syscall --nr-threads 4 --nr-iterations 1000
确定性模拟
使用种子复现错误。注意:模拟器使用旧版的“limbo”命名。
# Simulator
RUST_LOG=limbo_sim=debug cargo run --bin limbo_sim -- -s <seed>
# Whopper (concurrent DST)
SEED=1234 ./testing/concurrent-simulator/bin/run
栈用量
解析和转换表达式时,每深入一层就会递归一次,因此这些函数的栈帧大小决定了表达式的最大深度。scripts/stack/ 中的三个脚本可以测量栈用量。请使用发布版构建(cargo build --release --bin tursodb):调试版构建不会复用栈槽,因此其栈帧数据无法充分反映用户实际运行时的情况。运行每个脚本时加上 -h,即可查看所有选项。
# Frame size of each function, read from its prologue. -c compares two binaries.
scripts/stack/frame-sizes.sh 'translate::expr::'
scripts/stack/frame-sizes.sh -c /tmp/tursodb-main 'translate_expr$' 'parse_expr_inner$'
# Smallest stack that runs a SQL script, per binary. -S adds sqlite3.
scripts/stack/min-stack.sh -S -b /tmp/tursodb-main -b target/release/tursodb deep.sql
# Which functions use the stack at the deepest point (runs under lldb).
scripts/stack/stack-profile.sh deep.sql
每层递归调用一次的函数应尽量精简。将少见且体积较大的代码路径移至 #[inline(never)] 辅助函数中,例如 SQLite 的 SQLITE_NOINLINE。
架构参考
- 解析器 → 从 SQL 字符串生成 AST
- 代码生成器 → 从 AST 生成字节码
- 虚拟机 → 执行兼容 SQLite 的字节码
- 存储层 → B 树操作、分页
损坏问题调试
对于 WAL 损坏和数据库完整性问题,请使用 scripts 中的损坏调试工具。
详细用法请参阅 references/CORRUPTION-TOOLS.md。
评论
支持 Markdown