首页
/ Beads 的 Dolt 存储后端:嵌入式与服务端双模式、版本钉扎与备份迁移实战

Beads 的 Dolt 存储后端:嵌入式与服务端双模式、版本钉扎与备份迁移实战

2026-09-10 15:44:08作者:农烁颖Land

Beads 是一个面向 AI 编码代理(coding agent)的议题管理系统,它把 Dolt 作为唯一存储后端:一种自带 Git 语义(分支、合并、diff、push、pull)的版本化 SQL 数据库。本文围绕 docs/architecture/dolt.md 展开,系统讲解 Beads 为什么选择 Dolt、嵌入式与服务端两种运行模式的区别与切换、Dolt 2.2.0 版本钉扎的来龙去脉、bd dolt 命令族的远程同步与维护、跨后端备份迁移,以及多项目共享服务端与 macOS 集中部署等完整运维方案。读完你不仅能独立完成从 bd init 到多代理并发协作的部署,还能掌握数据库损坏恢复、迁移交接等关键实战技能。

为什么 Beads 选择 Dolt 作为存储后端

Beads 的架构文档开门见山:Dolt 是唯一存储后端,每一次写入都会自动提交到 Dolt 历史,从而在数据库层面提供完整的版本控制、分支与合并能力。选择 Dolt 的核心理由(见 docs/architecture/index.md):

  • 原生版本控制:提供 cell 级(单元格级)diff 与 merge,而不是文本行级合并——两个代理并发修改同一条议题的不同字段时,可以自动合并而不产生整行冲突;
  • 多写者支持:服务端模式(dolt sql-server)允许并发代理同时写入;
  • 内置历史:每次写入都会产生一个 Dolt commit,天然形成审计轨迹;
  • 原生分支:Dolt 分支独立于 Git 分支,可以基于议题数据建分支做实验;
  • 单二进制选项:嵌入式模式把 Dolt 引擎编译进 bd 二进制,单人使用无需安装任何服务端。

从源码看,嵌入式模式所链接的 Dolt 引擎版本记录在 go.mod 中:github.com/dolthub/dolt/go v0.40.5-0.20260715172757-a6690826d767,对应上游 v2.2.0 标签提交。也就是说,bd 二进制自带的 Dolt 引擎版本与 PATH 上独立安装的 dolt CLI 版本互不影响。

相比旧方案(SQLite 的二进制合并冲突、JSONL 的慢查询),Dolt 同时提供了 SQL 查询速度与正确的合并语义。架构文档也明确列出了取舍:本地优先意味着无实时协作、并发写需要服务端模式、同步到远端需要显式执行 push/pull。

快速上手:初始化与两种运行模式

安装 Dolt CLI(仅服务端模式需要)

嵌入式模式不需要任何额外安装——bd 二进制已包含一切。只有当你打算运行服务端模式,或想用 dolt sql 直接操作数据库时,才需要独立安装 dolt CLI。

务必安装指定版本,不要安装 releases/latest(原因见下节“版本钉扎”):

DOLT_VERSION=2.2.0   # 见下文 "Beads 钉扎的 Dolt 版本"

os=$(uname -s | tr '[:upper:]' '[:lower:]')
arch=$(uname -m | sed -e 's/^x86_64$/amd64/' -e 's/^aarch64$/arm64/')
curl -fsSL "https://github.com/dolthub/dolt/releases/download/v${DOLT_VERSION}/dolt-${os}-${arch}.tar.gz" \
  | tar -xz -C /tmp
sudo install -m 0755 "/tmp/dolt-${os}-${arch}/bin/dolt" /usr/local/bin/dolt

# 验证安装的确实是你要的版本
dolt version

如果你用 brew install dolt 安装,Homebrew formula 指向的版本未做钉扎,安装后务必用 dolt version 与下述钉扎版本核对。

版本钉扎:为什么固定 Dolt 2.2.0

Beads 将独立 dolt CLI 钉扎在 2.2.0。CI 通过 scripts/ci/install-dolt.sh 安装同一钉扎版本——该脚本注释明确要求保持与 internal/testutil/testdoltcommon.go 中的 DoltDockerImagescripts/ci/pull-dolt-image.sh 同步,避免测试套件跑在“从未发布过”的 Dolt 组合上。

钉扎的直接原因是上游回归:Dolt 2.3.0(2026-08-13 发布)破坏了 CALL DOLT_RESET('--hard')。实测约 5% 的新建数据库会出现该存储过程永久不可用——每次调用都返回 Error 1105 (HY000): context canceled,且对任何会话、任何新连接都如此,直至服务端进程生命周期结束。更隐蔽的是,SELECT 1CALL DOLT_CLEAN()CALL DOLT_CHECKOUT('.')CALL DOLT_COMMIT() 和软重置全部正常,只有真正需要硬重置时才会暴露。

官方测量数据(新建数据库后立即调用该过程):

Dolt 版本 DOLT_RESET('--hard') 损坏的新建库比例
2.1.8 0 / 40
2.2.0 0 / 60
2.3.0 3 / 60
2.3.1 3 / 100

2.3.1 之后的版本尚未测量。只有用同样的测量方法确认新版本干净后,才能抬高钉扎——而不是因为它“更新”。scripts/ci/install-dolt.sh 还额外强调了两点工程细节:下载失败会重试最多 3 次(间隔 5 秒),并用 dolt version 的精确 token 比对安装结果(子串匹配会放行 12.2.02.2.0-rc1 这类版本,导致回归测试环境漂移)。

钉扎而非跟随 latest 还有第二个独立原因:上游 releases/latest URL 解析到的是最近创建的 release 而非最高版本,因此可能“倒退”——v1.88.2 创建于 2026-08-17,晚于 v2.2.4 与 v2.3.0。

检测与修复已在运行的 2.3.x

一个数据库是否受影响,是在它创建那一刻决定的——同一台服务端上的两个数据库可能一个正常一个损坏,所以必须对每个关心的数据库、对着实际服务它的服务端逐一检测:

# 1. 工作集必须先干净:工作集脏时硬重置会丢弃未提交的修改。
#    如果返回任何行,先 commit 或清理,再执行第 3 步。
dolt sql -q "SELECT * FROM dolt_status"

# 2. 对照组——必须成功。若失败说明另有问题,第 3 步证明不了什么。
dolt sql -q "SELECT 1"

# 3. 对健康数据库而言,干净工作集上这是无操作。
dolt sql -q "CALL DOLT_RESET('--hard')"

判别标准:第 2 步成功而第 3 步返回 Error 1105 (HY000): context canceled——该数据库已受影响;两步都成功则未受影响。

故障存在于运行中的服务端进程而非磁盘上,因此重启 dolt sql-server 可以临时清除——已在受影响库上重启后复测验证过(同一服务端的健康库作为对照)。但重启会对每个数据库重新“掷骰子”,所以根治办法是切换到钉扎版本

这很重要,因为 bd flattenbd admin compact 里的 Dolt 历史压缩都以“硬重置 main 到临时分支”收尾,bd dolt pull / bd sync 的合并调停路径在放弃合并时也会回退到硬重置——在受影响的 2.3.x 库上,这些操作会在该步骤中止,被放弃的合并还会失去回滚。

新建项目

# 嵌入式模式(单写者、无需服务端——standalone 默认)
bd init

# 服务端模式(多写者,例如编排器场景)
gt dolt start           # 启动 Dolt 服务端
bd init --server        # 以服务端模式初始化

bd init 会把模式选择持久化到 .beads/metadata.json

从 SQLite 迁移(legacy)

bd migrate --to-dolt 命令已在 v0.58.0 移除。对于 0.50 之前带有 JSONL 数据的安装,使用迁移脚本:

scripts/migrate-jsonl-to-dolt.sh

迁移会自动创建备份,原始 SQLite 数据库保留为 beads.backup-pre-dolt-*.db。若迁移后遇到连接错误,参考 docs/reference/troubleshooting.md 中的排查章节。

运行模式详解

flowchart LR
    subgraph embedded["Embedded mode (default) — bd init"]
        bd1["bd process<br/>Dolt runs in-process"] --> d1[(".beads/embeddeddolt/<br/>single writer, file-locked")]
    end
    subgraph server["Server mode — bd init --server"]
        bd2["bd (agent 1)"] --> srv["dolt sql-server"]
        bd3["bd (agent 2)"] --> srv
        srv --> d2[(".beads/dolt/<br/>concurrent writers")]
    end

嵌入式模式(单机 / standalone)

进程内 Dolt 引擎,无需独立服务端,是 standalone 用户的默认模式。bd 二进制包含一切,bd init 后即可使用。

  • 单写者(同一时刻仅一个进程),通过文件锁强制;
  • 数据存放在代码仓库旁的 .beads/embeddeddolt/
  • bd dolt push 推送到 GitHub——代码与议题同仓库;
  • 零运维:无服务端、无端口、无 PID 文件。

除单机使用外,嵌入式模式还天然适合 CI/CD 流水线、Docker 容器、临时环境和“不应留下后台进程”的脚本(详见 docs/architecture/index.md 的 Dolt Server Mode 一节)。

服务端模式(多写者 / 编排器)

连接一个运行中的 dolt sql-server 以获得多客户端访问:

# 编排器方式启动服务端
gt dolt start

# 或手动启动
cd ~/.dolt-data/beads && dolt sql-server --port 3307
# 以服务端模式初始化
bd init --server

# 或通过环境变量切换
export BEADS_DOLT_SERVER_MODE=1
# .beads/config.yaml (server mode settings)
dolt:
  mode: server
  host: 127.0.0.1
  port: 3307
  user: root

连接参数可用 flag 或环境变量配置:

Flag 环境变量 默认值
--server-host BEADS_DOLT_SERVER_HOST 127.0.0.1
--server-port BEADS_DOLT_SERVER_PORT 3307
--server-socket BEADS_DOLT_SERVER_SOCKET (无;默认走 TCP)
--server-user BEADS_DOLT_SERVER_USER root
BEADS_DOLT_PASSWORD (无)

cmd/bd/dolt.go 的 CLI 定义看,bd dolt 命令族的服务端配置还支持 bd dolt set <key> <value> 方式设置 databasehostportuserdata-dir(默认 .beads/dolt),并可用 --update-config 同时写入 config.yaml 作为团队级默认值。注意:密码与 TLS 有意不设 set,以免机密落入 metadata.json,只能通过环境变量或凭据文件配置。

Unix 域套接字:使用 --server-socket 通过 Unix socket 连接而非 TCP,可避免并发项目间的端口冲突,也适合沙箱环境(如 Claude Code)——文件级访问控制比网络白名单更简单。Dolt 服务端须以 dolt sql-server --socket <path> 启动。注意 socket 模式不支持自动启动

需要切换到服务端模式的场景:

  • 多个代理同时写入;
  • 编排器多机架(multi-rig)部署;
  • 与远端对等节点做 federation 联邦同步。

何时用哪种模式

架构文档给出了一张权衡表(docs/architecture/index.md):嵌入式离线可用但无实时协作、单写者;服务端支持并发写但需要部署;cell 级合并不需要人工干预但要求初始设置正确。多克隆场景(多代理 AI 工作流、多 checkout 开发机、worktree 工作流)下并发 push/pull 存在竞态,建议切换克隆前先 bd dolt stop,自动化流程优先用嵌入式模式。

配置参考

config.yaml 核心配置

# .beads/config.yaml

# Dolt settings
dolt:
  # 写入后自动提交 Dolt 历史(默认:嵌入式开、服务端关)
  auto-commit: on        # on | off

  # 存储模式(默认:embedded)
  mode: embedded         # embedded | server
  # 服务端模式设置(仅 mode: server 时生效)
  host: 127.0.0.1
  port: 3307
  user: root
  # 密码:环境变量或凭据文件(见下文)

  # 共享服务端模式(GH#2377):所有项目共享 ~/.beads/shared-server/ 下的
  # 单个 Dolt 服务端。每个项目使用自己的数据库(基于 prefix)。
  # 消除多项目机器上的端口冲突并降低资源占用。
  shared-server: false   # true | false

环境变量

变量 用途
BEADS_DOLT_PASSWORD 服务端模式密码(最高优先级)
BEADS_CREDENTIALS_FILE 凭据文件路径(覆盖默认位置)
BEADS_DOLT_SERVER_MODE 启用服务端模式(设为 "1")
BEADS_DOLT_SERVER_HOST 服务端主机(默认:127.0.0.1)
BEADS_DOLT_SERVER_PORT 服务端端口(默认:3307,共享模式为 3308)
BEADS_DOLT_SERVER_TLS 启用 TLS(设为 "1" 或 "true")
BEADS_DOLT_SERVER_USER MySQL 连接用户
BEADS_DOLT_SHARED_SERVER 启用共享服务端模式(设为 "1" 或 "true")
DOLT_REMOTE_USER clone/push/pull 认证用户
DOLT_REMOTE_PASSWORD clone/push/pull 认证密码
BD_DOLT_AUTO_COMMIT 覆盖自动提交设置

这些环境变量与 bd dolt set 键的对应关系、密码与 TLS 只走环境变量/凭据文件的设计,均可在 cmd/bd/dolt.go 的命令 Long 描述中交叉印证。

凭据文件与密码解析

多服务端部署下,可用 INI 风格凭据文件替代逐项目环境变量。密码按 [host:port] 段查找,每个项目自动匹配其配置服务端的密码。

密码解析顺序

  1. BEADS_DOLT_PASSWORD 环境变量(最高优先级,既有行为);
  2. 凭据文件按 [host:port] 查找(使用解析后的运行时端口);
  3. 空字符串(无密码)。

端口解析注意:凭据查找所用的 [host:port] 匹配的是解析后的运行时端口(优先级:端口文件 → 环境变量 → config),不一定等于 metadata.json 里存的端口。使用 IAP 隧道时尤其要注意:若隧道把 remote:3307 映射到 localhost:3308,就把密码存在 [127.0.0.1:3308] 下,凭据文件才会匹配实际连接。

默认位置~/.config/beads/credentials(Linux/macOS)、%APPDATA%\beads\credentials(Windows),可用 BEADS_CREDENTIALS_FILE 覆盖。

文件格式

# ~/.config/beads/credentials
[127.0.0.1:3307]
password=localDevPassword

[beads.company.com:3307]
password=teamServerPassword

[10.0.1.50:3308]
password=officePassword

权限:Linux/macOS 下若文件可被组或其他用户读取,会向 stderr 打印警告(与 ssh 行为一致)。设置权限:

chmod 600 ~/.config/beads/credentials

Dolt 版本控制与自动提交

Dolt 维护独立于 Git 的版本历史:

# 查看议题在 Dolt commits 中的版本历史
bd history bd-42

# 显示当前分支与未提交改动
bd vc status

# 创建手动检查点
bd vc commit -m "Checkpoint before refactor"

自动提交行为:嵌入式模式(standalone 默认)下,每个 bd 写命令都会创建一个 Dolt commit:

bd create "New issue"    # 创建议题 + Dolt commit

服务端模式(编排器)下自动提交默认关闭,因为服务端自行管理事务生命周期——并发负载下每次写入都触发 DOLT_COMMIT 会导致 'database is read only' 错误。

批量操作(嵌入式)或显式提交(服务端)时覆盖默认行为:

bd --dolt-auto-commit off create "Issue 1"
bd --dolt-auto-commit off create "Issue 2"
bd vc commit -m "Batch: created issues"

cmd/bd/dolt.go 看,bd dolt commit 使用 CommitAll 而非 Commit:它的契约是提交工作集中任何未提交改动,包括外部改动与 config 表(服务端模式的 Commit 会排除 config 表,导致带外配置改动永远残留)。工作集干净时返回 Nothing to commit

数据维护:bd prunebd purge

bd prune 永久删除已关闭的非临时(non-ephemeral)beads 以回收存储并缩小自动导出;bd purge 对临时 beads(wisps、transient molecules)做同样的事。两者都要求 --force 才真正执行。

bd prune --older-than 30d              # 预览 30 天前关闭的 beads
bd prune --older-than 30d --force      # 删除它们
bd prune --older-than 90d --dry-run    # 带统计的详细预览
bd purge --force                       # 删除所有已关闭的临时 beads

引用感知保护bd prune 自动跳过“其 ID 出现在任何打开或进行中 beads 的 description、notes 或 comments 中”的已关闭 beads,防止误删下游工作仍在引用的 ADR、决策和验证 beads。清理已知过期引用时用 --ignore-references 覆盖:

bd prune --older-than 90d --ignore-references --force

bd purge 不受影响——临时 beads 的引用本身也是临时的。删除大量行后如需完整回收 Dolt 存储,接着执行 bd flatten

在 Dolt 2.3.x 上存储回收可能中途失败(再次回到版本钉扎问题):bd flattenbd admin compact 中的 Dolt 历史压缩都先构建临时分支再把 main 硬重置上去,bd dolt pull / bd sync 的合并调停路径在放弃合并时也回退到硬重置。受影响的库上该硬重置返回 Error 1105 (HY000): context canceledbd flattenbd admin compact 会停在该步骤,被放弃的合并失去回滚。检测与修复方法见上文“版本钉扎”一节。

后端间迁移与备份(bd backup

嵌入式模式与服务端模式之间可用 bd backup 双向迁移数据,两个方向都保留完整 Dolt 提交历史

bd export 不能替代该流程:JSONL 导出只包含 issues 表的议题记录,用于迁移与互操作;它不捕获 Dolt 分支、完整提交历史、工作集状态或其他非议题表。需要可恢复的数据库备份时,请用 bd backup 或手动 Dolt 备份。

服务端 → 嵌入式

  1. 从服务端模式项目创建备份

    # 在服务端模式项目目录中
    bd backup init /path/to/backup-dir
    bd backup sync
    
  2. 创建嵌入式模式新项目并恢复

    mkdir new-project && cd new-project
    bd init                  # 默认创建嵌入式模式项目
    bd backup restore --force /path/to/backup-dir
    

    --force 用备份内容覆盖刚初始化的数据库。恢复会自动:

    • 更新 metadata.json 以匹配恢复后的项目身份;
    • 注册备份目录供后续 bd backup sync 使用;
    • 回填嵌入式迁移跟踪器(schema_migrations)。
  3. 验证

    bd list
    bd backup status
    

嵌入式 → 服务端

  1. 从嵌入式模式项目创建备份

    # 在嵌入式模式项目目录中
    bd backup init /path/to/backup-dir
    bd backup sync
    
  2. 创建服务端模式新项目并恢复

    mkdir new-project && cd new-project
    bd init --server         # 创建服务端模式项目
    bd backup restore --force /path/to/backup-dir
    
  3. 验证

    bd list
    bd backup status
    

备份命令参考

命令 说明
bd backup init <path> 注册备份目标(文件系统或 DoltHub URL)
bd backup sync 推送数据库到已配置的备份目标
bd backup restore [path] 从备份目录恢复(--force 覆盖)
bd backup remove 注销备份目标
bd backup status 显示备份配置与最近同步时间

注意事项

  • 两种模式数据位置不同:.beads/embeddeddolt/(嵌入式)vs .beads/dolt/(服务端);
  • 备份目录是完整的 Dolt 备份而非 issues.jsonl 导出,可放在本地磁盘、NAS 或 DoltHub;
  • 若两个项目共享一个远程,也可通过 Dolt remotes(bd dolt push / bd dolt pull)迁移。

Dolt 远程仓库与同步

配置远程:bd dolt remote add

务必用 bd dolt remote add 配置远程,它会确保运行中的 Dolt SQL 服务端立即看到该远程。直接用 dolt CLI 添加的远程只写入文件系统配置,服务端可能要到重启后才可见。

# DoltHub(公有或私有)
bd dolt remote add origin https://doltremoteapi.dolthub.com/org/beads

# S3
bd dolt remote add origin aws://[bucket]/path/to/repo

# GCS
bd dolt remote add origin gs://[bucket]/path/to/repo

# Git SSH(GitHub、GitLab 等)
bd dolt remote add origin git+ssh://git@github.com/org/repo.git

# 本地文件系统
bd dolt remote add origin file:///path/to/remote

bd dolt remote add 通过 Dolt store API 注册远程。SQL remotes 是 bd dolt remote listbd dolt pushbd dolt pull 的唯一事实来源。

cmd/bd/dolt.go 的实现看,bd dolt push 对“未配置远程”的状态做了严谨判定:仅当 dolt_remotes 表确实为空磁盘上的 .dolt/repo_state.json 也无持久化远程时,才判定为“确实无远程”并打印提示、以 0 退出。这是因为服务端模式冷启动时 sql-server 可能上报空的 dolt_remotes,而远程其实已持久化在磁盘(GH#2118)——单靠空表会误报。

远程适配(remote adoption):当 rig 没有 Dolt 远程时,bd dolt push 可从 git origin 派生远程(git remote get-url),但需要用户同意——交互式确认或 --yes--no-adoptBD_NO_REMOTE_ADOPT=1 可完全禁用。适配成功后会把 sync.remote 持久化到 .beads/config.yaml

历史分叉与 schema fork 的处理bd dolt push / pull 内置了错误分类与恢复指引——本地与远端无共同祖先时提示 printDivergedHistoryGuidancebd bootstrap 保留远端 / bd dolt push --force 保留本地 / 删除本地库重新 bootstrap 三种方案);当合并因表主键集不同被拒绝(schema fork,通常是各克隆独立升级 bd 并各自跑了 schema 迁移所致),printAncestorPKMismatchGuidance 会给出“选一个权威克隆 bd dolt push --force,其余克隆 bd export --all 保存本地工作、删除 .beads/doltbd bootstrap 重克隆再 bd import”的完整剧本。

Push / Pull

bd dolt push
bd dolt pull
  • --force:覆盖远端改动(例如远端工作集有未提交改动时);
  • --remote <name>:推送到指定命名远程而非默认;
  • --strategy ours|theirs:嵌入式存储专用(#4992),解决自动解析器拒绝的冲突(如双方在最近一次同步后编辑了同一条议题);服务端模式存储请在 pull 报告冲突后用 bd conflicts resolve

对 git 协议远程、需凭据的外部服务端远程,以及凭据仅存在于当前 shell 的云远程,bd dolt push / bd dolt pull 会自动物化一个匹配的本地 CLI 远程再走 dolt CLI 传输。CLI 远程只是本地传输镜像,不是独立的配置来源。

若从旧版本升级且此前用裸 dolt remote add 添加过远程,请用 bd dolt remote add <name> <url> 重新注册使其对 SQL 可见。bd doctor 会在 Dolt Remote Migration 下报告仅 CLI 或失配的旧远程。

与 Git 共享仓库

Dolt 数据存储在 refs/dolt/data 下,与标准 Git refs(refs/heads/refs/tags/)分离。因此你可以放心地把 git+ssh:// 远程指向项目源码所在的同一仓库——议题历史随代码一起推送,互不干扰。

列出现有远程 / 删除远程

bd dolt remote list            # 显示 SQL 配置的远程
bd dolt remote remove origin   # 删除远程

贡献者克隆引导(Bootstrap)

当有人克隆使用 Dolt 后端的仓库时:

  1. 在克隆中运行 bd bootstrap
  2. 若 git remote 带 refs/dolt/data(经 bd dolt push 推送过),bd bootstrap 自动检测并从远程克隆数据库;
  3. 继续正常工作——所有既有议题都可用。

bd bootstrap无需任何手动步骤。自动检测会:探测 origin 是否有 refs/dolt/data;从远程克隆 Dolt 数据库(而非新建);配置 Dolt 远程供后续 bd dolt push/pull 使用。

.beads/config.yaml 中设置了 sync.remote,它优先于自动检测。任何 Dolt 兼容远程 URL 均支持(DoltHub、S3、GCS、file 或 git)。全新项目上,bd init 会自动检测 git origin 并持久化为 sync.remote,于是第一次 bd dolt push 就把 Dolt 历史发布到同一 git 远程的 refs/dolt/data

验证 bootstrap 成功

bd list              # 应显示议题
bd vc status         # 应显示当前分支、无未提交改动

多项目与服务端管理

共享服务端模式

在多项目机器上,每个项目默认启动自己的 Dolt 服务端。共享服务端模式在 ~/.beads/shared-server/ 运行单个 Dolt 服务端服务所有项目:

# 本项目启用(config.yaml 键)
bd config set dolt.shared-server true

# 或整机启用环境变量
export BEADS_DOLT_SHARED_SERVER=1

# 或在 init 时启用
bd init --prefix myproject --shared-server

收益

  • 项目间无端口冲突(单服务端在 3308 端口,避开编排器的 3307);
  • 资源占用低(一个进程替代多个);
  • 自动数据库隔离(每个项目使用自己的数据库名)。

工作原理

  • 服务端状态文件(PID、port、lock、log)位于 ~/.beads/shared-server/
  • Dolt 数据目录:~/.beads/shared-server/dolt/
  • 每个项目的数据库存储为子目录(如 ~/.beads/shared-server/dolt/myproject/);
  • 文件锁机制保证多项目并发访问安全;
  • 默认端口 3308(非 3307)以避免与编排器冲突,可用 BEADS_DOLT_SERVER_PORT 或 config.yaml 的 dolt.port 覆盖。

重要:共享服务端上的每个项目必须使用唯一 prefix(数据库名)。两个项目同 prefix 会共享同一数据库——若意外发生,项目身份检查会检测到失配并拒绝连接,防止静默数据损坏。使用 bd init --shared-server 时务必使用不同的 prefix。

# 从任意项目检查共享服务端状态
bd dolt status

# 显示完整配置(含共享模式)
bd dolt show

编排器服务管理

编排器提供集成的 Dolt 服务端管理:

gt dolt start            # 启动服务端(后台)
gt dolt stop             # 停止服务端
gt dolt status           # 显示服务端状态
gt dolt logs             # 查看服务端日志
gt dolt sql              # 打开 SQL shell

服务端运行在 3307 端口(避开 MySQL 的 3306)。

对应地,bd dolt start / bd dolt stop 管理当前项目的本地服务端:后台运行在按项目路径派生的端口上,PID 与日志存于 .beads/。从 cmd/bd/dolt.go 看,两者都有“远程主机守卫”:当配置的 Dolt 服务端主机非 localhost 时(dolt_server_host / dolt.host / BEADS_DOLT_SERVER_HOST),bd dolt start 拒绝在本机启动服务端,bd dolt stop 拒绝停掉本地 PID 状态(那只是残留,配置的外部服务端仍在运行,GH#3545/GH#3518)。bd dolt stop 在托管代理(proxied)服务端场景下还支持 --force 恢复无法验证或遗留的进程记录,但仅当进程可执行文件能匹配到 bddolt 且命令行能关联到本工作区时才允许发送信号。

编排器数据目录

<town-root>/.dolt-data/
├── hq/                  # Town beads (hq-*)
├── my-project/          # Project rig (mp-*)
├── beads/               # Beads rig (bd-*)
└── other-project/       # Other rig (op-*)

macOS 集中式 Dolt 服务端(LaunchAgent)

不使用编排器、但仍想在 macOS 上为多个项目运行一个常驻 Dolt 服务端时,可用自定义 LaunchAgent 替代逐项目嵌入式实例。

为什么不用 brew services start dolt 安装 brew install dolt 后最自然的下一步就是 brew services start dolt,但 Homebrew formula 运行 dolt sql-server不带 --config 参数,而 Dolt 不会从工作目录自动发现 config.yaml——配置文件必须用 --config <file> 显式传入。

自定义 LaunchAgent 安装步骤

安装 Dolt 并初始化数据目录。对照钉扎版本检查安装版本——Homebrew formula 未钉扎:

brew install dolt
dolt version
cd /opt/homebrew/var/dolt && dolt init

为 3307 端口配置 Dolt:

# /opt/homebrew/var/dolt/config.yaml
log_level: info

listener:
  host: 127.0.0.1
  port: 3307
  max_connections: 100

behavior:
  autocommit: true

创建 LaunchAgent plist:

cat > ~/Library/LaunchAgents/com.local.dolt-server.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.local.dolt-server</string>
    <key>ProgramArguments</key>
    <array>
        <string>/opt/homebrew/bin/dolt</string>
        <string>sql-server</string>
        <string>--config</string>
        <string>/opt/homebrew/var/dolt/config.yaml</string>
    </array>
    <key>WorkingDirectory</key>
    <string>/opt/homebrew/var/dolt</string>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/opt/homebrew/var/log/dolt.log</string>
    <key>StandardErrorPath</key>
    <string>/opt/homebrew/var/log/dolt-error.log</string>
</dict>
</plist>
EOF

加载并验证服务:

launchctl load ~/Library/LaunchAgents/com.local.dolt-server.plist
mysql -h 127.0.0.1 -P 3307 -u root -e "SELECT 1"

让 beads 指向集中式服务端:

export BEADS_DOLT_SERVER_MODE=1
export BEADS_DOLT_SERVER_PORT=3307

服务管理:

# 停止
launchctl unload ~/Library/LaunchAgents/com.local.dolt-server.plist

# 重启
launchctl unload ~/Library/LaunchAgents/com.local.dolt-server.plist
launchctl load ~/Library/LaunchAgents/com.local.dolt-server.plist

# 查看日志
tail -f /opt/homebrew/var/log/dolt.log

从独立项目交接给托管编排器

当既有 standalone 项目后来被纳入托管 city 或编排器时,要避免两个 Dolt 服务端成为同一 beads 数据库名的“双主”。常见的脑裂症状是:.beads/dolt-server.port 指向旧的独立服务端,而 shell 环境用 BEADS_DOLT_PORTBEADS_DOLT_SERVER_PORTbd 指向托管服务端。

迁移前检查:

bd doctor
bd dolt status

bd doctor 在运行时托管端口与本地端口文件不一致时会告警。该告警仅用于诊断:在独立 store 被导出并导入托管服务端之前,不要删除本地端口文件。

安全的手动交接:

# 在独立项目目录中,不带托管 city 端口覆盖:
unset BEADS_DOLT_PORT BEADS_DOLT_SERVER_PORT
bd backup
bd export > /tmp/beads-standalone.jsonl
bd dolt stop

# 然后进入托管 city 环境,导入到其 Dolt 服务端:
bd import /tmp/beads-standalone.jsonl
bd doctor

bd doctor 显示一个健康 store 且导入的议题数正确后,将旧的本地 Dolt 数据目录归档而非立即删除。在托管 city 被推送或以其他方式快照之前,保留该备份。

高级用法:用 dolt CLI 直接操作

dolt CLI 允许高级用户直接操作数据库。数据目录取决于模式:.beads/embeddeddolt/(嵌入式)或 .beads/dolt/(服务端)。

分支

cd .beads/dolt   # 嵌入式模式为 .beads/embeddeddolt
dolt branch feature-x
dolt checkout feature-x

时间旅行

dolt log
dolt checkout <commit-hash>
dolt sql -q "SELECT * FROM issues"

Diff 与 Blame

dolt diff main feature-x
dolt blame issues

故障排查

服务端未运行

症状:服务端模式下出现连接拒绝错误。

failed to create database: dial tcp 127.0.0.1:3307: connect: connection refused

修复

gt dolt start        # 编排器命令
# 或
gt dolt status       # 检查是否在运行

Bootstrap 未运行

症状:全新克隆上 bd list 什么都不显示。

检查

ls .beads/dolt/            # 不应存在(bootstrap 前)
BD_DEBUG=1 bd list         # 查看 bootstrap 输出

强制 bootstrap

rm -rf .beads/dolt         # 移除损坏状态
bd list                    # 重新触发 bootstrap

数据库损坏

症状:查询失败、数据不一致。

诊断

bd doctor                  # 基础检查
bd doctor --deep           # 完整校验
bd doctor --server         # 服务端模式检查(如适用)

恢复选项

  1. 修复可修复项

    bd doctor --fix
    

    注意 docs/architecture/index.md 的警告:运行 bd doctor --fix 前务必先 cp -r .beads .beads.backup 备份、用 bd doctor --dry-run 预览、用 bd doctor(无 flag)复查;--fix 可能删除它判定为循环的依赖,包括合法的父子关系。

  2. 从远程重建

    rm -rf .beads/dolt
    bd list                  # 重新触发 bootstrap
    

误将 .beads/dolt/ 提交进 Git

  1. 更新 gitignore:bd doctor --fix
  2. 从 git 跟踪移除:git rm --cached -r .beads/dolt/(或 .beads/embeddeddolt/);
  3. 提交移除:git commit -m "fix: remove accidentally committed dolt data"
  4. 如需从历史中清除,使用 BFG Repo-Cleaner 或 git filter-repo

锁竞争(嵌入式模式)

症状:“database is locked” 错误。

嵌入式模式是单写者(通过文件锁强制)。需要并发访问时切换到服务端模式,见“后端间迁移与备份”一节。

迁移清理

SQLite 迁移成功后,可能残留备份文件:

.beads/beads.backup-pre-dolt-20260122-213600.db
.beads/sqlite.backup-pre-dolt-20260123-192812.db

确认 Dolt 正常工作后可安全删除:

# 验证 Dolt 可用
bd list
bd doctor

# 然后清理(建议等待一段时间)
rm .beads/*.backup-*.db

建议:删除前至少保留备份一周。

相关文档

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.16 K
2.78 K
kernelkernel
deepin linux kernel
C
34
18
docsdocs
暂无描述
Markdown
904
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
933
1.86 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
862
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.96 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.38 K
1.47 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
535
606
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
549
398
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Markdown
77
23