9.4 KiB
syncdb 产品与技术设计
1. 产品定位
syncdb 是基于 Go 的轻量级 Web 数据库同步服务,支持 MySQL 和 MongoDB,面向开发、测试和运维环境。
支持范围
| 来源 | 目标 | 范围 |
|---|---|---|
| MySQL | MySQL | MVP |
| MongoDB | MongoDB | MVP |
| MySQL | MongoDB | 基础字段映射 |
| MongoDB | MySQL | 基础字段映射 |
首期不实现实时 CDC、跨库事务、双向实时同步、任意脚本执行和自动删除目标数据。
2. 单包交付
项目只生成一个 syncdb 可执行文件,包含 REST API、MySQL/MongoDB 适配器、同步引擎、任务调度、审计模块和通过 go:embed 嵌入的 Vue 前端。运行时外部文件为 config.yaml、data/syncdb.db 和 logs/。
后端使用 Go net/http,不使用 Spring Boot。前端使用 Vue 3 + TypeScript,构建后的 web/dist 必须在 Go 编译前生成。
3. 系统架构
浏览器
↓ HTTP/REST + SSE
Go Web 服务
├── API 与鉴权
├── 数据源管理
├── MySQL Adapter
├── MongoDB Adapter
├── 结构检查与字段映射
├── 同步引擎
├── 任务调度与有限并发
├── 脱敏处理
└── SQLite 元数据仓储
4. 核心功能
数据源管理
- 创建、编辑、删除和测试 MySQL/MongoDB 连接。
- 凭据加密保存,接口不得返回密码,日志不得输出密码或含凭据的 URI。
- 数据源带开发、测试、生产环境标签;生产数据源默认禁止作为目标。
对象浏览与结构检查
MySQL 检查 database、table、column、primary key、unique key、index 和 foreign key。MongoDB 检查 database、collection、_id、index、collection options 和 JSON Schema validator。
MongoDB 文档结构使用采样推断,记录字段路径、类型和出现频率,并标记为“推断结构”;不得据此自动删除或修改目标结构。
数据同步
- 支持全量、主键/
_id范围、时间字段增量和条件过滤。 - 支持 Insert、Replace、Update、Upsert、Skip、Fail 冲突策略。
- 支持分页读取、批量写入、最大行数、超时、取消和有限重试。
- 默认只新增或更新,不自动删除目标记录;dry-run 不写目标库。
- 长时间全量同步不使用显式事务包裹,减少锁持有时间。
跨数据库字段映射
支持字段重命名、嵌套字段路径、默认值、空值处理、忽略字段、JSON/数组转换和基础类型转换。
{"source":"users","target":"users","mapping":{"id":"_id","user_name":"profile.name","email":"email","created_at":"createdAt"}}
必须处理自增主键与 MongoDB _id、DECIMAL 精度、时区、NULL/字段缺失、数组/嵌套文档和 MySQL JSON。
Binlog 与已执行 SQL
仅针对 MySQL 数据源提供 Binlog 浏览能力,用于查看增量事件和定位同步问题。支持按数据源、时间范围、Binlog 文件、位置、数据库、表、事件类型和关键字筛选;详情展示时间、事务 ID、文件与位置、数据库/表、事件类型、主键和脱敏后的变更内容。默认只读,不支持 Web 修改、删除或重放 Binlog。
同步服务记录自己生成并执行的 SQL,形成可检索的 SQL 审计记录。记录任务、批次、目标数据源、起止时间、SQL 类型、影响行数、耗时、状态、错误信息和脱敏后的 SQL。敏感值不得原样保存;超长 SQL 保存摘要、哈希和可配置长度的预览。
建议接口:
GET /api/binlog/events
GET /api/binlog/events/{id}
GET /api/sql-executions
GET /api/sql-executions/{id}
GET /api/sql-executions/{id}/sql
读取 Binlog 需要 MySQL 复制读取权限,并设置文件大小、时间范围和查询频率限制,避免影响主库。syncdb 只保存查询索引和必要的脱敏事件摘要。
脱敏与执行
支持手机号、邮箱、姓名、身份证号等字段的掩码、哈希、随机替换、清空和截断。任务包含源/目标、对象、模式、过滤器、映射、脱敏规则、批次大小、冲突策略和计划。执行记录保存处理/成功/跳过/失败数量、错误信息和配置版本。
任务使用 goroutine 执行,但必须限制并发数,并支持超时、取消、有限重试和优雅关闭。前端使用 SSE 获取实时进度。
5.1 SQL 导出压缩包
针对 MySQL 数据源提供 SQL 导出功能,生成可下载的压缩包。支持仅结构、仅数据或结构加数据,支持指定表、过滤条件、分批导出和可选脱敏。服务端将压缩包写入临时制品目录并以流方式下载,避免把完整导出文件加载到内存。
压缩包内容建议为:
manifest.json
schema.sql # 请求结构时生成
data/
users.sql
orders.sql
大型导出必须拆分为大小受限的 SQL 文件。manifest.json 记录数据源类型、对象列表、导出选项、行数、校验和、创建时间和工具版本,不得记录凭据或未脱敏的敏感数据。
导出任务异步执行,并通过 SSE 推送进度。下载需要鉴权,文件名使用 syncdb-export-{id}.tar.gz,制品在可配置时间后过期并由清理任务删除。生产数据导出需要显式确认,默认启用脱敏。SQL 值必须使用安全转义,不得将不可信输入直接拼接到 SQL 语句中。
推荐接口:
POST /api/exports/sql
GET /api/exports
GET /api/exports/{id}
GET /api/exports/{id}/download
DELETE /api/exports/{id}
GET /api/exports/{id}/events
5.1 复制账号权限向导
页面必须明确提示:主库只有 SELECT 的只读账号不足以完成从库同步。提供权限向导,生成可审核、可复制或下载的创建账号和删除账号 SQL,默认不自动执行。
账号分工:
syncdb_reader 主库:全量导出和元数据读取
syncdb_repl 主库:复制连接和 Binlog 读取
syncdb_replica_admin 从库:配置、启动、停止和查看复制
syncdb_applier 从库:可选,限制复制事务的应用权限
创建和删除 SQL 必须显示目标主机、数据库范围和风险提示;执行需要显式确认并写入审计日志。密码单独生成或输入,不写入文档和日志。
MySQL 8 示例模板:
-- 主库
CREATE USER 'syncdb_reader'@'syncdb_host' IDENTIFIED BY '<reader-password>';
GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES ON `app`.* TO 'syncdb_reader'@'syncdb_host';
CREATE USER 'syncdb_repl'@'replica_host' IDENTIFIED BY '<replication-password>';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'syncdb_repl'@'replica_host';
-- 从库
CREATE USER 'syncdb_replica_admin'@'syncdb_host' IDENTIFIED BY '<admin-password>';
GRANT REPLICATION SLAVE, REPLICATION CLIENT, CONNECTION_ADMIN ON *.* TO 'syncdb_replica_admin'@'syncdb_host';
删除模板:
-- 主库
DROP USER IF EXISTS 'syncdb_reader'@'syncdb_host';
DROP USER IF EXISTS 'syncdb_repl'@'replica_host';
-- 从库:停止复制并确认依赖后执行
DROP USER IF EXISTS 'syncdb_replica_admin'@'syncdb_host';
DROP USER IF EXISTS 'syncdb_applier'@'syncdb_host';
页面生成 SQL 前检查 MySQL 版本、主从角色、账号主机限制、现有用户和运行中的复制配置。不得建议删除仍被运行中的 Replica 使用的账号;复制权限和 syncdb_applier 的精确授权需根据版本和复制配置由 DBA 审核。
5. REST API
GET/POST/PUT/DELETE /api/datasources[/{id}]
POST /api/datasources/{id}/test
GET /api/datasources/{id}/objects
POST /api/schema/diff | /api/schema/plan | /api/schema/apply
GET/POST/PUT/DELETE /api/tasks[/{id}]
POST /api/tasks/{id}/run | /api/tasks/{id}/cancel
GET /api/executions[/{id}]
GET /api/executions/{id}/errors | /api/executions/{id}/events
GET /api/health
6. 代码组织
cmd/syncdb/main.go
internal/api/ internal/config/ internal/datasource/
internal/adapter/mysql/ internal/adapter/mongo/
internal/syncengine/ internal/mapping/ internal/masking/
internal/task/ internal/execution/ internal/repository/
web/src/ web/dist/ web/embed.go migrations/
适配器统一实现连接测试、对象列表、对象检查、记录读取和批量写入接口;MySQL 表元数据与 MongoDB 集合元数据保持独立建模。
7. Drone CI/CD
流水线顺序:前端构建 web/dist → go test ./... → 嵌入前端并交叉编译 → 生成压缩包 → 构建/推送 Docker 镜像。仅 Git tag(如 v1.0.0)发布正式版本。
建议使用 CGO_ENABLED=0、-trimpath 和 -ldflags="-s -w"。最终镜像只包含证书、时区数据和 syncdb 二进制。
8. 安全原则
- 破坏性结构操作默认关闭,并需要单独确认。
- 同步前检查连接、权限、目标对象、白名单和最大数据量。
- 生产到非生产默认启用脱敏。
- 失败时停止后续步骤并保存错误明细。
- 审计数据源、任务、脱敏规则、执行和高风险确认操作。
- 元数据默认使用 SQLite,未来可增加 MySQL 元数据库支持多实例。
9. 实施顺序
- 初始化 Go 服务、配置、SQLite 迁移和健康检查。
- 实现 MySQL/MongoDB 数据源管理与连接测试。
- 实现对象浏览、元数据检查和基础 API。
- 实现同类型全量同步、批量写入、Upsert、取消和进度记录。
- 实现跨数据库字段映射和类型转换。
- 实现脱敏、SSE、任务调度和审计。
- 完成 Vue 页面、
go:embed单包构建和 Drone CI 发布。