Beads 的 Dolt 存储后端:嵌入式与服务端双模式、版本钉扎与备份迁移实战
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 中的 DoltDockerImage 及 scripts/ci/pull-dolt-image.sh 同步,避免测试套件跑在“从未发布过”的 Dolt 组合上。
钉扎的直接原因是上游回归:Dolt 2.3.0(2026-08-13 发布)破坏了 CALL DOLT_RESET('--hard')。实测约 5% 的新建数据库会出现该存储过程永久不可用——每次调用都返回 Error 1105 (HY000): context canceled,且对任何会话、任何新连接都如此,直至服务端进程生命周期结束。更隐蔽的是,SELECT 1、CALL 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.0 或 2.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 flatten、bd 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> 方式设置 database、host、port、user、data-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] 段查找,每个项目自动匹配其配置服务端的密码。
密码解析顺序:
BEADS_DOLT_PASSWORD环境变量(最高优先级,既有行为);- 凭据文件按
[host:port]查找(使用解析后的运行时端口); - 空字符串(无密码)。
端口解析注意:凭据查找所用的 [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 prune 与 bd 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 flatten 与 bd admin compact 中的 Dolt 历史压缩都先构建临时分支再把 main 硬重置上去,bd dolt pull / bd sync 的合并调停路径在放弃合并时也回退到硬重置。受影响的库上该硬重置返回 Error 1105 (HY000): context canceled,bd flatten 与 bd admin compact 会停在该步骤,被放弃的合并失去回滚。检测与修复方法见上文“版本钉扎”一节。
后端间迁移与备份(bd backup)
嵌入式模式与服务端模式之间可用 bd backup 双向迁移数据,两个方向都保留完整 Dolt 提交历史。
bd export 不能替代该流程:JSONL 导出只包含 issues 表的议题记录,用于迁移与互操作;它不捕获 Dolt 分支、完整提交历史、工作集状态或其他非议题表。需要可恢复的数据库备份时,请用 bd backup 或手动 Dolt 备份。
服务端 → 嵌入式
-
从服务端模式项目创建备份:
# 在服务端模式项目目录中 bd backup init /path/to/backup-dir bd backup sync -
创建嵌入式模式新项目并恢复:
mkdir new-project && cd new-project bd init # 默认创建嵌入式模式项目 bd backup restore --force /path/to/backup-dir--force用备份内容覆盖刚初始化的数据库。恢复会自动:- 更新
metadata.json以匹配恢复后的项目身份; - 注册备份目录供后续
bd backup sync使用; - 回填嵌入式迁移跟踪器(
schema_migrations)。
- 更新
-
验证:
bd list bd backup status
嵌入式 → 服务端
-
从嵌入式模式项目创建备份:
# 在嵌入式模式项目目录中 bd backup init /path/to/backup-dir bd backup sync -
创建服务端模式新项目并恢复:
mkdir new-project && cd new-project bd init --server # 创建服务端模式项目 bd backup restore --force /path/to/backup-dir -
验证:
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 list、bd dolt push、bd 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-adopt 或 BD_NO_REMOTE_ADOPT=1 可完全禁用。适配成功后会把 sync.remote 持久化到 .beads/config.yaml。
历史分叉与 schema fork 的处理:bd dolt push / pull 内置了错误分类与恢复指引——本地与远端无共同祖先时提示 printDivergedHistoryGuidance(bd bootstrap 保留远端 / bd dolt push --force 保留本地 / 删除本地库重新 bootstrap 三种方案);当合并因表主键集不同被拒绝(schema fork,通常是各克隆独立升级 bd 并各自跑了 schema 迁移所致),printAncestorPKMismatchGuidance 会给出“选一个权威克隆 bd dolt push --force,其余克隆 bd export --all 保存本地工作、删除 .beads/dolt、bd 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 后端的仓库时:
- 在克隆中运行
bd bootstrap; - 若 git remote 带
refs/dolt/data(经bd dolt push推送过),bd bootstrap自动检测并从远程克隆数据库; - 继续正常工作——所有既有议题都可用。
除 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 恢复无法验证或遗留的进程记录,但仅当进程可执行文件能匹配到 bd 或 dolt 且命令行能关联到本工作区时才允许发送信号。
编排器数据目录
<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_PORT 或 BEADS_DOLT_SERVER_PORT 把 bd 指向托管服务端。
迁移前检查:
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 # 服务端模式检查(如适用)
恢复选项:
-
修复可修复项:
bd doctor --fix注意 docs/architecture/index.md 的警告:运行
bd doctor --fix前务必先cp -r .beads .beads.backup备份、用bd doctor --dry-run预览、用bd doctor(无 flag)复查;--fix可能删除它判定为循环的依赖,包括合法的父子关系。 -
从远程重建:
rm -rf .beads/dolt bd list # 重新触发 bootstrap
误将 .beads/dolt/ 提交进 Git
- 更新 gitignore:
bd doctor --fix; - 从 git 跟踪移除:
git rm --cached -r .beads/dolt/(或.beads/embeddeddolt/); - 提交移除:
git commit -m "fix: remove accidentally committed dolt data"; - 如需从历史中清除,使用 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
建议:删除前至少保留备份一周。
相关文档
- 同步概念 —— 跨机同步的概念模型(Dolt 作为事实来源、线格式、反模式)
- 同步设置指南 —— 多台电脑间设置同步
- Federation 联邦设置指南 —— 点对点联邦同步
- 完整配置参考
- 依赖与门禁
- Git 集成 —— Git worktrees 与受保护分支
- 故障排查
- 架构总览 —— 数据模型、数据流、目录布局与恢复模型
- Dolt CLI 实现 ——
bd dolt命令族源码 - CI Dolt 安装脚本 —— 钉扎版本安装与校验的参考实现
- JSONL 迁移脚本 —— legacy 数据迁移
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.21 K637- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python290
cherry-studio🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端TypeScript2 K146
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python46267
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go20043
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java33951