news 2026/9/29 3:52:11

开源一款可视化 MySQL 数据同步工具 DataMove:零代码玩转全量 + Canal 增量同步

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开源一款可视化 MySQL 数据同步工具 DataMove:零代码玩转全量 + Canal 增量同步

副标题:一个基于 RuoYi-Vue 二次开发的轻量级 ETL 平台,专治"DBA 跑路 / DataX 配错 / Canal 命令行劝退"。

一、为什么要造这个轮子?

我们团队过去三年踩过太多次坑:

场景现状痛点
业务库拆分(订单库 → 订单中台库)用 DataX 写 JSON字段映射要手写 joiner,运维同事上手成本高
实时订阅 binlog部署 Canal + 写 Kafka 消费要懂 canal 协议 + 位点 + 多线程 ack,错一次就丢数据
DBA 离职交接几个脚本散落在跳板机新人接手无从下手,权限审计一塌糊涂
临时数据修复程序员手动INSERT ... SELECT容易把生产主键写崩,且没日志

于是就有了DataMove——把数据同步做成"配置即任务":选源库 → 选目标库 → 选表 → 点启动,再在浏览器里看日志、收钉钉告警。

项目代码完全开源,二级拿到手就能直接用。

在线体验:http://8.140.200.84/

官网:http://8.140.200.84/website/


二、它能做什么?

┌────────────────────────────────────────────────────────────┐ │ DataMove 能力地图 │ ├──────────────┬─────────────────────────────────────────────┤ │ 数据源 │ MySQL 5.7 / 8.x,多源并存,密码 AES 加密存储 │ │ 全量同步 │ 按主键 ID / 按时间字段,断点续传、幂等覆盖 │ │ 增量同步 │ 基于 Canal 1.1 订阅 binlog,自动 ACK + 位点 │ │ SQL 工作台 │ CodeMirror 编辑器,多语句、Ctrl+Enter 执行 │ │ 数据浏览 │ 在线分页浏览任意已注册数据源(带行数统计) │ │ 同步日志 │ 批次明细 + 总进度,支持 CSV 导出 │ │ 告警 │ 钉钉 Webhook 主动推送(启动失败/中断/对账异常)│ │ 授权 │ MAC + LicenseKey 一机一绑,离线可用 │ │ 权限 │ admin / operator 两级 RBAC │ └──────────────┴─────────────────────────────────────────────┘

对比 DataX / Canal-adapter / DTS 这些"老炮",DataMove 的优势是零代码 + 全中文 + 自带可视化 + 自带授权,适合中小团队"开箱即用"。


三、整体架构

前端 (Vue 2 + Element UI)后端 (SpringBoot 2.7)存储基础设施HTTP / SwaggerJDBC 分批TCP 11111订阅 ROW binlog数据源/任务/日志SQL 工作台Controller 层数据源服务任务服务FullSyncEngine全量引擎CanalSyncEngine增量引擎SQL 引擎License 服务SyncLogService异步日志钉钉告警MySQL 8.0元数据 + 业务RedisToken 缓存Canal Server订阅 binlog

核心模块仅 ~4 个 Java 包:

com.ruoyi.datamove ├── datasource // 数据源管理 ├── task // 同步任务 CRUD ├── engine │ ├── full // FullSyncEngine (断点续传 + 幂等) │ ├── incr // CanalSyncEngine (增量 + 位点 ACK) │ └── log // SyncLogService (批次明细) ├── browse // 在线浏览数据 ├── license // 离线授权校验 └── log // 日志导出 controller

四、关键技术点 1:全量同步的"双引擎 + 断点续传 + 幂等"

4.1 两种同步模式

模式适用场景WHERE 片段
按主键 ID几乎所有业务表WHERE id > #{lastId} LIMIT #{batchSize}
按时间字段没有自增主键的表 / 日志型表WHERE time > #{lastTime} OR (time = #{lastTime} AND id > #{lastIdInBatch})

按时间模式里"同秒数据"的处理是关键:先用time = #{lastTime} AND id > #{lastIdInBatch}把同秒内剩余行捞完,再推进lastTime,彻底解决"漏数据 / 重复拉取"。

4.2 断点续传的核心原则

整批 INSERT 成功 → 才更新lastSyncMaxId/lastSyncTime

伪代码:

while (有下一批) { rows = selectByCondition(lastId); try { tx.begin(); batchInsertOrUpdate(rows); // ON DUPLICATE KEY UPDATE updateProgress(lastId = rows.lastId); // ✅ 仅成功才推进 tx.commit(); } catch (Exception e) { tx.rollback(); // 下次启动会从 lastId 重新拉这一批 } }
  • 崩溃重启:自动从上次lastSyncMaxId继续,不会丢也不会重复。
  • 重复执行安全:INSERT ... ON DUPLICATE KEY UPDATE是 MySQL 幂等标准写法。

4.3 整批ON DUPLICATE KEY UPDATE而不是REPLACE INTO:

REPLACE会先DELETE旧行,对带AUTO_INCREMENT的表会改主键、并触发级联删除;ON DUPLICATE KEY UPDATE只 update 既有列,幂等且不破坏外键。


五、关键技术点 2:Canal 增量同步 + 位点 ACK

5.1 同步流程

启动 → CanalConnector.connect() → subscribe(filter) → 循环 getWithoutAck(1000) ↓ apply(CanalEntry) → JDBC applyRowData() ↓ getAck(batchId) // ✅ 处理成功才 ack ↓ 更新 sync_canal_position 表

5.2 反向回环防护

源端写入的目标库也会产生 binlog,会被 Canal 误"二次同步"。 DataMove 用库名白名单 + 任务级 destination两层过滤:

  • Canal 配置里只订阅datamove库的data_move_test表(精确过滤)。
  • 每个任务绑定独立destination,一个任务一个订阅通道。

5.3 失败回滚

try { apply(events); // 写目标库 connector.ack(batchId); // ✅ 推进位点 } catch (Exception e) { connector.rollback(batchId); // ❌ 不 ack,下次重做 sync_canal_position 不更新; 触发钉钉告警; }

关键设计:位点更新必须在ack之后,否则一旦程序在 update position 前崩溃,重启会丢事件。


七、关键技术点 3:SQL 工作台(运维救场神器)

数据同步之外,DataMove 还附带一个 Web 版的 SQL 工作台:

  • CodeMirror 6 编辑器,支持 MySQL 关键字高亮 + 智能补全(Ctrl + Space)。
  • 多语句执行,按分号拆分,每个语句单独展示结果。
  • 查询结果 1000 行上限,超过提示;可一键导出Excel / CSV。
  • Ctrl + Enter执行当前选中或全部,效率直逼本地 Navicat。
  • 操作历史:每次执行保留在页面内,点 tag 可回填到编辑器。

DBA 哥哥再也不用远程登录服务器开 SSH 隧道了。


八、同步日志:批次级粒度 + CSV 导出

SyncLogService会在每个批次结束后异步写入sync_task_log:

字段含义
task_id任务 ID
task_name任务名
sync_modeFULL / INCR
batch_no批次号(增量任务记录 binlog 起止位点start_key/end_key)
batch_rows本批处理行数
total_rows累计已同步行数
cost_ms本批耗时
statusSUCCESS / FAILED
error_msg失败信息(FAILED 时填)
  • 全量任务:批次号天然递增。
  • 增量任务:批次号 = canal message batchId;start_key/end_key是binlog:offset,让管理员一眼能定位到具体 binlog 位置。
  • 支持按任务 ID、状态筛选,一键 CSV 导出(字段含start_key / end_key)供运维追溯。

十、告警:钉钉 Webhook 主动推送

触发场景推送内容
任务启动失败 / 数据源连不上[DataMove告警] 任务[xxx] 启动失败: 源库连接失败
全量中断 / 增量 binlog 断开[DataMove告警] 任务[xxx] 已中断, 请查看日志
单批次错误率超过阈值[DataMove告警] 任务[xxx] 失败 N 条, 错误样本: ...

每条任务支持独立 Webhook,运维在钉钉群里就能秒级响应。


十一、十分钟跑起来

# 1. 初始化 MySQL mysql -uroot -p < sql/datamove.sql # 2. 启动后端 mvn clean package -DskipTests java -jar target/datamove.jar # → Swagger 文档: http://localhost:8080/swagger-ui/index.html # 3. 启动前端 cd ruoyi-ui npm install npm run dev # → http://localhost:80 账号 admin / admin123 # 4. (可选)Docker 起 Canal docker compose -f docker/canal/docker-compose.yml up -d

首次登录后 4 步即可同步:

  1. 授权管理→ 确认 License 状态(首次启动自动 30 天试用)。
  2. 数据源→ 添加源库与目标库 → 点 "测试连接"。
  3. 任务→ 新建任务(全量或增量)→ 点 "启动" → 在 "同步日志" 看实时进度。
  4. 钉钉→ 在任务里填 Webhook → 异常自动推送到钉钉群。

十二、安全与权限

  • 密码 / LicenseKey / 数据源密码全部入库前 AES 加密。
  • 前端回显只显示前 2 位 **** 后 2 位,明文绝不出现。
  • Spring Security + JWT,路由级权限。
  • 内置两种角色:
    • admin:全权,可改 License、可改数据源密码。
    • operator:仅查看任务、启停任务、看日志,零数据源操作权限。
  • admin默认密码首次登录强制修改。

十三、性能与稳定性经验

  1. JDBC 批写 1000 行/批:经测试,addBatch + executeBatch比单条 INSERT 快 50~80 倍;1000 行是吞吐与事务回滚成本的甜点。
  2. setFetchSize(batchSize):MySQL 驱动必须显式设才能流式取,否则会一次性把所有数据塞进内存(OOM 重灾区)。
  3. Canal 失败回滚:见上文 §5.3。
  4. 钉钉限流:批量失败不并发推,最多保留最近 5 条事件,避免被风控。

十四、Roadmap(二期规划)

  • [ ] DDL 同步(库表结构变更自动跟随)
  • [ ] 多线程极速同步(按主键区间分片并行)
  • [ ] 数据差异对账 + 一键修复
  • [ ] 数据脱敏(手机号 / 身份证 / 邮箱)
  • [ ] PostgreSQL / Oracle / 达梦支持
  • [ ] SaaS 多租户 Web 版

十五、写在最后

DataMove 不是一个万能 ETL 平台,它的定位非常清晰:

给中小企业 / 个人 / 外包团队的"零代码 MySQL 同步工具"。

如果你正被 DataX JSON 折磨、被 Canal 命令行劝退、被 DBA 离职搞得焦头烂额,不妨试试:

  • gitee : https://gitee.com/qingtian2023/datamove.git
  • 文档:README.md+ Swagger UI 一站式
  • 反馈:欢迎提 Issue / PR

如果你觉得这个项目有帮助,欢迎Star ⭐鼓励一下作者,这也是开源最大的动力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 3:50:57

OpenSpec实战:规范驱动开发如何用CLI管好需求与代码同步

1. 为什么是 OpenSpec&#xff1a;规范驱动开发要解决的实际痛点1.1 从一次真实“文档翻车”说起前阵子我们团队接了一个中型 Web 项目&#xff0c;需求散落在飞书文档、Confluence、微信群聊天记录里。开发到第二周&#xff0c;产品经理口头确认的一个“小改动”被谁忘掉了&am…

作者头像 李华
网站建设 2026/9/29 3:50:56

I2C多主机仲裁与时钟延展:从原理到实战避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 3:49:38

【YOLO系列】YOLO v5 网络结构图+代码:从 SPPF 到 ONNX 的配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 3:49:08

校园网安全巡检实战:日志留存、弱口令排查与终端抽查指南

简介&#xff1a;这份文档面向中小学、幼儿园、职校及其他教育单位的信息安全负责人与网络管理员&#xff0c;围绕教育系统网络与信息安全巡检的实际工作展开&#xff0c;帮助读者理清巡检流程、检查要点与整改方向。内容涵盖巡检计划安排、重要设备日志备份、数据备份方式核查…

作者头像 李华
网站建设 2026/9/29 3:47:39

GPT-5+Codex登陆Azure AI:TaoToken统一Key接入配置与验证指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华