0. 先和大家打个招呼吧 
- 一名在职数据开发工程师;
- 最开始是有这个idea,因为工作中需要,然后发现了一个开源项目litestream,它是只对sqlite3备份,然后我就想到可以开发对其它数据库的,特别是嵌入式数据库,进行实时备份,因为自己有技术背景,但是go语言不熟悉,所以就先准备好架构设计等草稿,然后让Trae帮我完成代码开发工作
1. Demo 简介
是什么: WALtch 是一个命令行数据库备份与恢复工具,支持 MySQL 和 H2 数据库,将备份数据写入 S3 兼容对象存储(或本地文件系统),并提供 SHA-256 校验、gzip 压缩、AES-256-GCM 加密,以及只读的 Web 监控仪表盘。
面向谁: 开发者、运维人员、小型团队——任何需要为数据库建立可靠备份策略、但不希望依赖复杂 SaaS 平台的人。
主要功能:
- MySQL 全量备份 + binlog 增量备份 + 时间点恢复(PITR)
-
全量备份基于 mysqldump,附带 binlog 位点信息
-
增量备份通过 go-mysql 协议实时采集 binlog 事件,存储为 JSONL 格式
-
恢复时可指定
--target-time,自动找到最近全量备份并重放增量到指定时间点
- H2 数据库全量备份与恢复
-
通过 H2 Shell 的 SCRIPT 命令导出,RunScript 命令导入
-
自动清理 Shell 输出中的框架格式,转为纯 SQL
- 只读监控仪表盘
-
深色主题 Web 界面,展示存储后端、备份总数、总大小、各实例状态
-
所有备份和回滚操作通过 CLI 执行,仪表盘不提供任何操作按钮
2. Demo 创作思路
灵感来源: 在日常开发中,我经常需要为本地开发环境的 MySQL 和 H2 数据库做备份。现有的工具要么太重(需要完整部署一套备份平台),要么太轻(缺乏校验、加密、增量备份能力)。我想要的是一把「瑞士军刀」——一个二进制文件、一份配置文件,就能完成从备份到恢复的全流程。
想解决的问题:
-
数据库备份工具往往需要复杂的部署和运维,对小团队不友好
-
缺少内建的校验机制,备份数据损坏了也不知道
-
增量备份和时间点恢复是 MySQL 的刚需,但开源方案少且配置繁琐
-
需要同时支持多种数据库(MySQL + H2),而不是每个数据库配一套工具
为什么做这个方向: 数据库备份是每个项目的底线需求,但市面上缺少一个"开箱即用、多数据库、带校验和加密、支持 S3 存储"的轻量级 CLI 工具。WALtch 填补了这个空白。
3. Demo 体验地址
源码(GitHub): https://github.com/simonaries/WALtch
快速体验步骤:
# 1. 克隆仓库
git clone https://github.com/YOUR_USERNAME/WALtch.git
cd WALtch
# 2. 编译
make build
# 3. 配置环境变量(编辑 .env-dev 填入你的 S3 凭据和 MySQL 密码)
set -a; . ./.env-dev; set +a
# 4. 启动 Docker 测试环境(MySQL 8.0 + H2 + MinIO S3)
docker compose -f tests/docker-compose.yml up -d
# 5. 运行全量备份
./waltch backup --config config.yaml --instance prod-mysql
# 6. 查看备份列表
./waltch list --config config.yaml
# 7. 校验备份
./waltch verify --config config.yaml --instance prod-mysql --backup-id <id>
# 8. 启动监控仪表盘
./waltch server --config config.yaml --address :9090
# 打开 http://localhost:9090
Docker 一键启动(含 MySQL + H2 + MinIO):
docker compose -f tests/docker-compose.yml up -d
4. TRAE 实践过程
整个 WALtch 项目完全使用 TRAE IDE 开发完成。以下是开发过程中的关键步骤。
步骤 1:需求分析与架构设计
首先向 TRAE 提供了完整的设计文档 WALtch设计稿.md,包含项目目标、用户场景、功能设计、技术栈选型、数据模型。TRAE 分析了设计文档后,帮我梳理了清晰的模块划分:
-
CLI 层(cobra 命令)
-
配置层(YAML + 环境变量展开)
-
存储层(本地/S3 抽象 + 加密管道)
-
核心层(元数据管理、保留策略、调度器)
-
插件层(MySQL 插件、H2 插件)
┌──────────────────────────────────────────┐
│ CLI │
│ backup / daemon / list / verify / restore│
└───────────────────┬──────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ Config Loader │
│ YAML + env expansion + validation │
└───────────────────┬──────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ Core │
│ Scheduler / Metadata / Retention │
└─────────────┬────────────────┬───────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Database Plugin Layer│ │ Storage Layer │
│ MySQL / H2 │ │ Local / S3 │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ MySQL / H2 Database │ │ Object Store / FS │
└──────────────────────┘ └──────────────────────┘
Session ID:
.599693127070900:b0326145b241940e7af4ee3f93e3422f_6a4e55125fbdca606d7e96ff.6a4e6cb65fbdca606d7e99c3.6a4e6cb6774efe7aeebb38c0:Trae CN.T(2026/7/8 23:28:54)
.599693127070900:2bd6c3f35d949dd70f46beaa4f278c3b_6a4e55125fbdca606d7e96ff.6a4e6c1c5fbdca606d7e99b0.6a4e6c1b774efe7aeebb38bf:Trae CN.T(2026/7/8 23:26:20)
.599693127070900:97356b9f5c510ffb858da88771ef8a2f_6a4e55125fbdca606d7e96ff.6a4e69ba5fbdca606d7e9994.6a4e69ba774efe7aeebb38be:Trae CN.T(2026/7/8 23:16:10)
.599693127070900:3370304b8753d770884863e7465fa455_6a4e55125fbdca606d7e96ff.6a4e5c7e5fbdca606d7e9701.6a4e5c7e774efe7aeebb38bd:Trae CN.T(2026/7/8 22:19:42)
步骤 2:核心模块逐一实现
TRAE 按照设计文档中的里程碑,逐步生成了各核心模块代码:
| 模块 | 文件 | 说明 |
|---|---|---|
| 配置 | internal/config/config.go |
YAML 解析 + ${VAR} 环境变量展开 + 校验 |
| 存储 | internal/storage/s3.go, local.go, crypto.go |
S3/本地存储抽象 + AES-256-GCM 加密管道 |
| 元数据 | internal/core/metadata.go |
备份元数据 JSON 存储,路径规范 metadata/{db_type}/{instance}/{id}.json |
| MySQL 插件 | internal/plugin/mysql/plugin.go, binlog.go, replayer.go |
mysqldump 全量 + binlog 增量采集 + JSONL 重放 |
| H2 插件 | internal/plugin/h2/plugin.go |
SCRIPT 导出 + RunScript 恢复 |
| CLI | cmd/backup.go, restore.go, server.go 等 |
9 个子命令,cobra 框架 |
| Web 仪表盘 | cmd/web/index.html, app.js, styles.css |
只读监控界面,每 15 秒自动刷新 |
步骤 3:编译调试与修复
编译过程中遇到了多个需要修复的问题,TRAE 帮我逐一排查和解决:
-
GTID 解析兼容 MySQL 8.0:MySQL 8.0 的 mysqldump 输出中 GTID 带版本注释
/*!80000 '+'*/,原正则表达式无法匹配,导致增量备份无法使用 GTID 同步。TRAE 将正则更新为SET @@GLOBAL\.GTID_PURGED=.*?'([^']+)'\s*; -
SIGINT 时增量备份刷新失败:用户 Ctrl+C 取消增量备份时,上下文也被取消,导致 S3 上传失败。修复为刷新时使用独立的 detached context
-
恢复时权限不足:mysqldump 输出包含
SET @@GLOBAL.GTID_PURGED等需要 SUPER 权限的语句,修复为恢复前自动剥离这些语句
# 编译成功
$ go build -o waltch .
$ ./waltch version
waltch version dev (commit=dev built=2026-07-08T14:46:08Z)
# 全部测试通过
$ go test ./...
ok waltch/cmd
ok waltch/internal/config
ok waltch/internal/core
ok waltch/internal/plugin/h2
ok waltch/internal/plugin/mysql
ok waltch/internal/storage
步骤 4:端到端验证
对真实 RustFS S3 端点 + MySQL 8.0 容器进行了完整的端到端验证:
| 验证项 | 命令 | 结果 |
|---|---|---|
| 全量备份 | waltch backup --instance prod-mysql |
type=full size=3863813 checksum=OK |
| 增量备份 | waltch backup --incremental |
type=incremental segments=1 |
| 校验 | waltch verify --backup-id <id> |
status=ok |
| 全量恢复 | waltch restore --backup-id <id> |
5 条数据恢复 |
| PITR 恢复 | waltch restore --target-time "..." |
9 条数据恢复(全量 + 增量重放) |
| 清理策略 | waltch prune --dry-run |
keep=3 delete=0 |
| 监控仪表盘 | waltch server |
/api/status 返回 JSON,/ 返回 HTML |
开发心得
用 TRAE 开发的最大感受: 从设计文档到完整可运行的项目,TRAE 承担了 90% 以上的代码生成工作。我只需要做三件事——写清楚需求、验证结果、反馈问题。遇到编译错误时,把错误信息直接发给 TRAE,它就能定位到具体的 API 变更(如 go-mysql v1.5.0 的 EventHeader 结构变化)并给出修复方案。
踩过的坑:
-
go-mysql 库的 v1.5.0 API 与文档有差异,EventHeader 不包含 LogFilename 字段,需要通过 RotateEvent 自行追踪
-
GTIDEvent 的字段名是 SID/GNO 而非文档中的 GTIDNext
-
XIDEvent 的 GTIDSet 字段实际名为 GSet
这些问题 TRAE 都通过查看源码和 API 文档帮我快速定位并修复了。
项目技术栈
| 层级 | 技术 |
|---|---|
| 语言 | Go 1.23 |
| CLI | spf13/cobra |
| 配置 | gopkg.in/yaml.v3 + 环境变量展开 |
| 存储 | AWS SDK Go v2(S3 兼容)、本地文件系统 |
| MySQL | go-mysql-org/go-mysql(binlog 协议)、go-sql-driver/mysql |
| H2 | H2 Shell / RunScript(外部进程调用) |
| 加密 | crypto/aes(AES-256-GCM)、crypto/sha256 |
| 压缩 | compress/gzip |
| 日志 | log/slog |
| 前端 | 原生 HTML + CSS + JS(内嵌,无框架依赖) |
| 测试 | Docker Compose(MySQL 8.0 + H2 + MinIO) |
报名帖链接
本项目使用 TRAE IDE 开发完成。所有备份和回滚操作通过 CLI 执行,Web 仪表盘仅提供只读监控。





