# gync **Repository Path**: coderzhouyu/gync ## Basic Information - **Project Name**: gync - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-02 - **Last Updated**: 2026-10-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gync **单二进制异构数据库实时同步工具 —— Jync 捷同的 Go 实现** 无 JVM、无 cgo、无外部依赖。一个纯 Go 编译的静态二进制,内嵌 Web 控制台, 在内置多种数据库之间建立持续同步链路:游标增量检测、断点续传、幂等写入。 > 本项目是 [Jync 捷同](https://github.com/vfaner/jync)(MIT,Java/Spring Boot)的 Go 重写。 > 目标:保留其一致性设计与信创数据库覆盖,换取静态单文件、毫秒级启动、可交叉编译至 > amd64 / arm64 / loong64 的交付形态。 ## 快速开始 ```bash # 构建(默认 CGO_ENABLED=0,产出静态单文件) make build # → dist/gync(.exe) # 启动 ./dist/gync # 或 go run ./cmd/gync # 一个文件,三件事 gync # 起服务(默认子命令,:8080) gync verify [...] # 数据库校验矩阵(信创实测) gync seed [...] # 生成 SQLite 演示库 gync version # 打印版本 # 打开控制台 # http://localhost:8080 初始账号 admin / view,密码 123456(登录后请立即修改) ``` ### 五分钟演示(无需任何外部数据库) ```bash # 五分钟演示:生成 demo/src.db(含 2 行)与 demo/tgt.db gync seed # 或 go run ./cmd/gync seed ``` 然后在控制台里: 1. **数据库连接** → 新建两条 SQLITE 连接,数据库字段分别填 `demo/src.db`、`demo/tgt.db` (源库用途选「源数据库连接」,目标库选「目标数据库连接」) 2. **项目** → 新建项目,选好源与目标 3. 进入**项目详情** → 勾选 `t_user` → 保存勾选 → 「检测游标策略」(应显示 TIMESTAMP) 4. 点「立即同步」→ 目标库出现两行数据;改源库后再同步,变更即被捕获 仓库内附演练脚本:`demo/smoke.ps1`(全流程自动化)、`demo/sync-once.ps1`(单轮触发)、 `demo/schedule-check.ps1` + `demo/sched-check.yml`(调度与审计验证,轮询 1s)、 `demo/structure-check.ps1`(结构同步:目标库无表 → 自动建表 → 验列与行数)、 `demo/conversion-check.ps1`(转换审阅 + AI 供应商:覆盖存取/空覆盖拒绝/探测真失败)、 `demo/verify-matrix.ps1` + `demo/verify-sqlite.yml`(数据库校验矩阵)。 ### 结构同步演示(目标库无表) ```bash gync seed -dir ./demo -empty-target # 目标库不建表 gync seed -dir ./demo -verify # 校验列与行数(缺表退出码 1) ``` ### 数据库校验(信创实测矩阵) `gync verify` 子命令对单个或一批数据库执行全链路冒烟: ``` 连接 → 对象清单 → 建临时表(可移植 DDL)→ 探列/主键/游标策略 → 真实 upsert 路径写入 → 读回 → 重放幂等 → 改一行 → 闭区间窗口查询 → 删临时表 ``` 每一步 PASS/FAIL 并带耗时与错误原文——一次运行即能定位不兼容的层。 ```bash # 单目标 gync verify -type DM -host 127.0.0.1 -port 5236 -db SYSDBA -user SYSDBA -password xxx # 矩阵(填好 demo/verify-example.yml) gync verify -config demo/verify-example.yml # 无需外部实例的自检(走 generic 方言的 UPDATE-then-INSERT 兜底路径) make verify-sqlite ``` 退出码 0 = 全部通过;1 = 有失败。密码亦可用环境变量 `GYNC_VERIFY_PASSWORD`(单目标模式)。 首次启动自动创建: | 路径 | 用途 | |---|---| | `./data/gync.db` | 元数据库(SQLite,连接 / 项目 / 游标 / 锁 / 变更日志) | | `./snapshots/` | 元数据快照目录 | ## 配置(application.yml,可缺省) 字段与 Jync 的 `sync.*` 保持一致,存量配置可直接迁移: ```yaml server: port: 8080 sync: data-dir: ./data snapshot-dir: ./snapshots poll-interval: 2000 # 轮询间隔(毫秒) batch-size: 500 # 目标库每批写入行数 fetch-size: 1000 max-retries: 3 safety-lag-ms: 1000 # 时间戳水位线安全回退 row-count-audit-interval-ms: 60000 full-compare-max-rows: 20000 lock-ttl-ms: 300000 # 同步锁租约(毫秒) structure-sync: true # 结构同步(建表 / 补列) crypto-password: 请改成你自己的强口令 # ← 必须修改 crypto-salt: 请改成你自己的16位十六进制盐 # ← 必须修改 ai-enabled: true ``` 环境变量可覆盖关键项:`GYNC_PORT`、`GYNC_DATA_DIR`、`GYNC_CRYPTO_PASSWORD`、 `GYNC_CRYPTO_SALT`、`GYNC_AI_ENABLED`。 ## 支持的数据库(默认纯 Go 构建) | 家族 | 数据库 | 驱动 | 幂等 upsert 语法 | |---|---|---|---| | MySQL 系 | MySQL / MariaDB / TiDB / OceanBase(MySQL 模式) / GBase 8a | `go-sql-driver/mysql` | `INSERT ... ON DUPLICATE KEY UPDATE` | | PostgreSQL 系 | PostgreSQL / openGauss / 金仓 KingBase / 瀚高 HighGo / 海量 Vastbase | `jackc/pgx/v5` | `INSERT ... ON CONFLICT (pk) DO UPDATE` | | Oracle 系 | Oracle / 达梦 DM | `sijms/go-ora` / 达梦官方纯 Go 驱动 | `MERGE INTO ... USING (SELECT ? FROM DUAL)` | | SQL Server | SQL Server | `microsoft/go-mssqldb` | `MERGE ... WITH (HOLDLOCK)` | | 其他 | 无原生 upsert 时 | — | `UPDATE-then-INSERT` 兜底 | 暂不支持(默认构建明确拒绝并给出原因):崖山 YashanDB(官方驱动依赖 C 库)、 神通 Oscar(无纯 Go 驱动)。 ## 设计要点(与 Jync 对齐) - **增量窗口闭区间**:先读 `MAX(游标列)` 作水位线,取 `游标列 > 上次游标 AND 游标列 <= 水位线`,同步期间的新写入自然落入下个窗口。 - **先提交后推进**:目标库数据提交成功后才持久化游标;中途崩溃则重放同一窗口, 由幂等写入收敛(至少一次投递 → 结果上恰好一次)。 - **时间戳安全回退**:持久化水位线时回退 `safety-lag-ms`,避免「开始早、提交晚」 的事务被永久跳过。 - **游标策略自动识别**:16 个「最后修改时间」列名 → TIMESTAMP;7 个「创建时间」 列名或单列数字主键 → IDENTITY;无游标且行数小 → FULL_COMPARE 每周期全表 upsert; 否则 NONE(仅首次全量)。列类型必须确为时间类型(VARCHAR 的 `update_time` 不认, 二进制 `rowversion` 不认)。 - **自动调度**:项目启用后按 `poll-interval` 轮询,或用 Quartz 风格 Cron (5/6 字段,支持 `*` `?` `a-b` `a/n` `*/n` 与名称 MON-FRI/JAN;L/W/# 明确拒绝); 每个项目一个 goroutine,启用即先跑一轮(重启补齐)。 - **补跑合并**:运行中再点击「立即同步」或调度落点重叠时,只登记**一轮**补跑 —— 连点 N 次合并为一轮,不会排队(`internal/syncengine/coordinator.go`)。 - **行数审计**:每 `row-count-audit-interval-ms` 核对源/目标行数,仅在项目空闲时执行, 发现漂移记入变更日志(AUDIT 类型);只报告不自动修复。 - **结构同步**(`structure-sync: true`):读取源库列定义,按目标方言生成可移植 CREATE TABLE(类型映射 + 各产品上限裁剪:Oracle VARCHAR2 4000 越界降 CLOB、 精度裁剪到上限并保留小数位、未声明精度不产生 `DECIMAL(0,0)`;不可移植的默认值 丢弃而非生成非法 DDL);目标缺表则建表,已存在则 ADD 缺失列;建表语句哈希存入 快照,一致则短路。类型/长度变更不自动应用(记入日志待人工)。 结构同步失败则跳过该表的数据同步并记日志。 - **单飞执行**:数据库租约行锁(可跨进程、崩溃后可接管)+ 进程内协调器。 - **转换审阅与 AI 起草**:视图/过程的机械转换(函数名映射、`FROM DUAL` 移除、 `NOW()`→裸关键字)严格只在字符串字面量、引号标识符与注释**之外**生效; 检测到过程控制流(BEGIN/DECLARE/LOOP 等)**拒绝机械转换**并明示原因 (语法合法但语义不同的静默错误比报错更严重)。人工覆盖落库(空白覆盖拒绝—— 空串比没有更糟);AI 只产出候选,经审阅后以覆盖形式生效,永不参与同步。 AI 探测发**真实请求**(max_tokens=1),密钥错/模型名错/Base URL 差路径都会 真实暴露;供应商互斥启用由服务端事务保证。 - **权限模型**:所有写操作皆 POST,POST 一律要求管理员;访客只读; 密码 bcrypt 存储,连接密码与 AI 密钥 AES-256-GCM 加密入库(`enc:` 前缀,兼容历史明文)。 ## 项目结构 ``` cmd/gync/ 唯一入口(子命令分发:serve 默认 / verify / seed / version) internal/config/ YAML 配置加载与校验 internal/model/ 领域实体与枚举(含 18 种数据库描述符) internal/store/ SQLite 元数据库(内嵌 schema、CRUD、租约锁、覆盖、AI 供应商) internal/crypto/ AES-256-GCM + bcrypt internal/dialect/ SQL 方言:引号 / 占位符 / upsert / 窗口查询 / 类型映射 / DDL internal/dbdriver/ database/sql 驱动注册表与 DSN 构造 internal/metadata/ 对象清单 / 结构读取 / 源定义读取(按方言族) internal/converter/ 机械 SQL 体转换(字面量/注释安全,拒绝控制流) internal/ai/ OpenAI 兼容 / Anthropic 客户端(探测 + SSE 流式起草) internal/seed/ 演示库生成(gync seed) internal/verify/ 数据库校验矩阵(gync verify) internal/syncengine/ 游标策略、水位线、批次写入、租约锁、协调器、Cron、审计、结构同步 internal/scheduler/ 轮询/Cron 双模调度 internal/i18n/ 中英文案 internal/web/ 控制台(embed 模板与静态资源、会话、权限中间件) ``` ## 测试 ```bash make test # go test ./... make vet # go vet ./... ``` 覆盖:方言不变量(占位符与冲突子句)、游标策略(含 VARCHAR/二进制类型否决)、 游标编解码往返、加密往返与密钥错误、存储层(种子账号幂等、锁租约与过期接管、 进度 upsert、项目级联删除),以及**端到端同步**(SQLite 双库:首次全量、 增量新增、增量更新、重放幂等、无主键全量整表替换、游标持久化)。 另有控制台全流程测试(登录/鉴权/同源校验、连接与项目台账、转换审阅:真实 SQLite 视图 → 机械转换 → 覆盖保存/删除 → AI 起草拒绝路径)、调度器双模 (轮询/Cron 立即首跑、禁用即停)、校验矩阵(`gync verify` 走 SQLite 真库)、 配置与驱动 DSN 构造、Cron 解析(含 L/W/# 拒绝)等。交叉插桩总覆盖率 ~80%; 未覆盖部分集中在 `internal/metadata` 的 MySQL/PG/Oracle/SQLServer 读取器—— 它们需要真实实例,由 `gync verify` 在信创环境实测校验。 ## 路线图 - [x] v0.1 骨架:配置 / 元数据 / 方言 / 引擎 / 控制台 / 连接管理 - [x] v0.2 项目全流程:项目 CRUD、对象勾选(表/视图/过程)、游标策略检测、 立即同步(后台运行 + 状态轮询)、启停标记、重置进度、变更日志 - [x] v0.3 调度与审计:轮询与 Cron 双模调度、补跑合并、行数审计(漂移记日志)、 调度状态展示(schedule / nextRun) - [x] v0.4 结构同步:类型映射(含上限裁剪与精度裁剪)、可移植 CREATE TABLE / ADD COLUMN、快照比对短路、缺表自动建表、新增列自动传播 - [x] v0.5 转换审阅与 AI 起草:机械转换(字面量/注释安全)、拒绝控制流、 左右对照审阅页、人工覆盖存取、AI 供应商管理(真实探测/互斥启用)、 SSE 流式起草(候选 + 不确定项清单) - [x] v0.6 校验矩阵:`gync verify` 全链路冒烟(连接/对象/建表/写入/读回/ 幂等/更新/窗口/清理),单目标与 YAML 矩阵两模式,退出码可接 CI; 附 `demo/verify-example.yml` 与 `demo/verify-matrix.ps1` - [ ] 待办:接入真实信创实例跑矩阵,逐库确认后写入「已验证」清单 ## 许可证 MIT。衍生自 Jync(Copyright (c) vfaner,MIT)。