跳到主要内容

崩溃问题

Goose 通过大规模测试套件进行了充分测试。 但缺陷仍可能出现,并在某些情况下导致崩溃。 本页提供排查 Goose 崩溃的实用信息。

崩溃类型

主要有以下几类崩溃:

  • 终止信号: 进程以 SIGSEGV(段错误)、SIGABRT 等方式退出。这类问题本不应发生,请提交 issue

  • 内部错误: 某些操作可能触发 Internal Error,例如:

    INTERNAL Error:
    Attempted to access index 3 within vector of size 3

    发生内部错误后,Goose 会进入受限模式,后续任意操作都会报错:

    FATAL Error:
    Failed: database has been invalidated because of a previous fatal error.
    The database must be restarted prior to being used again.
  • 内存不足错误: Goose 崩溃也可能是操作系统杀掉进程的表现。 例如,很多 Linux 发行版会运行 OOM reaper / OOM killer 进程,通过杀进程释放内存,避免系统内存耗尽。 如果你的 Goose 会话被 OOM reaper 杀掉,请参阅“OOM errors”页面

恢复数据

如果 Goose 在崩溃前正向持久化数据库文件写入, 数据库旁边可能会有一个名为 ⟨database_filename⟩.wal 的 WAL(write-ahead log)文件。 要从 WAL 恢复数据,只需在该持久化数据库上启动新的 Goose 会话。 Goose 会回放 write-ahead log 并执行checkpoint 操作,将数据库恢复到崩溃前状态。

崩溃排查

使用最新 stable 与 preview 构建

Goose 持续在改进,因此你遇到的问题可能已经在代码中被修复。 先尝试升级到 latest stable build。 若仍无法解决,再尝试 preview build(也称 nightly build)。

如果你希望使用包含某个 open pull request 的版本, 可以尝试从源码构建

搜索已有 issue

导致崩溃的 bug 可能已经被他人报告。 请在 GitHub issue tracker 中用报错信息搜索相关问题。 Goose 社区很活跃,常能找到可行的临时 workaround。

禁用查询优化器

部分崩溃由 Goose 查询优化器导致。 可先关闭优化器并重跑查询,以判断是否相关:

PRAGMA disable_optimizer;

如果查询成功执行,说明崩溃由一个或多个优化规则引起。 要进一步定位具体规则,可尝试选择性禁用优化规则,这样仍可保留其余优化收益。

尝试隔离问题

有些问题来自组件与扩展之间的交互,或仅在特定平台/客户端语言出现。 通常可以把问题逐步缩小到更小范围。

用纯 SQL 复现

问题也可能来自客户端库差异。 为判断这一点,请使用 Goose CLI 客户端通过纯 SQL 复现。 若在命令行客户端无法复现,通常说明问题更可能在客户端库层面。

更换硬件环境

根据经验,不少崩溃来自硬件异常(硬盘过热、CPU 超频等)。 因此值得在另一台机器上运行相同负载进行验证。

拆解查询

建议将复杂查询拆分为多个更小查询,并分别使用不同 Goose 扩展与 SQL 特性。

例如,若你有一个针对 AWS S3 数据集并执行两次 join 的查询,可改写为多步流程: 先手动下载数据文件并加载到 Goose, 再分别执行第一、第二个 join。 若多步流程仍在某一步崩溃,那么触发崩溃的那条子查询就是很好的最小可复现样例;若多步流程不再崩溃,可再逐步拼回原查询并观察哪一步重新引入错误。 无论哪种情况,你都能更清楚地理解根因,并可能立即得到可用的 workaround。 最后,建议将这些结论一并提交 issue

提交 Issue

如果你发现 Goose 崩溃,请考虑在 GitHub issue tracker 提交 issue,并附上最小可复现样例