资讯动态

MySQL数据同步实战:Dbsyncer全量增量同步配置指南

发布时间:2026/9/10 0:26:25 来源:尧图企业网站定制
做数据同步的活儿说实话很多人第一反应是写脚本定时查源库比对差异再UPDATE INSERT。刚开始数据量小还好表一多、字段一多脚本就成了一坨浆糊改一个字段要连带改一堆逻辑而且增量这块几乎没法做得干净。后来我在项目里换成了开源数据同步中间件Dbsyncer专门拿来处理MySQL到MySQL的全量和增量同步操作完全是可视化页面省心不少。这篇就把我实际配置Dbsyncer的过程、踩过的坑、以及一些常规文档里不会写的细节一次性说清楚。先说结论Dbsyncer是一个支持多种数据源之间的全量、增量、双向同步的开源中间件针对MySQL to MySQL这种常见场景它基本能做到开箱即用。适合后端开发、DBA、数据运维以及所有被“多库数据同步”折磨过的人。下面从选型、部署、配置到排错完整过一遍。1. 为什么选Dbsyncer而不是自己写同步脚本1.1 数据同步的常见场景与痛点先聊聊我遇到的实际诉求。当时业务上有一个主业务库数据量越来越大报表查询、统计分析直接跑在主库上慢查询把事务拖得够呛。最朴素的解法是搞一个只读报表库让报表和统计都走那边主库专心写业务。但问题来了报表库的数据怎么从主库过去如果只是全量很简单mysqldump导一次就完事了。但业务是活的每时每刻都有新订单、新用户报表库隔五分钟就过期五分钟。所以必须做增量同步而且最好能低延迟地追着主库跑。类似的需求还包括测试环境刷数据、灾备库就近同步、异构系统间分发数据反正“两个库之间要把数据对上”这件事是开发日常里的高频痛点。自己写同步脚本的问题很明显全量好写增量难写。增量要么靠时间字段轮询对DELETE无能为力对UPDATE也不一定抓得到要么去解析binlog这等于自己造轮子要管binlog协议、位点断点、事件解析、异常恢复工作量直接爆炸。所以我决定找一个现成的同步工具。1.2 Dbsyncer做了什么Dbsyncer本质上是一个数据同步中间件核心能力是帮你在不同数据源之间搬运数据。它内置了多种连接器比如MySQL、Oracle、SQL Server、PostgreSQL、ES、Kafka等也支持在一个任务里做全量同步、增量同步或者两者之间的衔接。MySQL to MySQL的场景下它的工作方式大致是这样全量同步时直接按表查询源库数据批量写入目标库增量同步时它把自己伪装成一个MySQL从库拉取源库的binlog解析出INSERT/UPDATE/DELETE事件再转换成SQL写到目标库。这个机制的好处是只要源库开了binlog并有相应的复制权限就能拿到一条不落地增量数据不需要业务表加时间字段也不会漏掉删除操作。更让我觉得顺手的是Dbsyncer有Web控制台可以在页面上配置数据源、映射表、字段对应关系还能看同步状态、延迟、异常日志。比起改脚本改配置这种可视化操作在交付和排查的时候舒服太多了。1.3 和其他工具的简单对比有人可能会问同类工具不少比如Canal、DataX、Maxwell为什么选Dbsyncer我说下自己的理解。DataX是离线同步工具做全量批量导数很猛但增量实时性不是它主打的Canal专注于MySQL binlog解析底子很好但它更偏向基础组件你要自己写客户端消费、自己管理位点还要额外接一套投递逻辑Maxwell则偏向把binlog转成JSON事件流适合对接消息队列。Dbsyncer更像一个“开箱即用的同步平台”既能全量也能增量有UI界面能管理多张表映射关系单机部署也简单。当然如果是要支撑几十万QPS的极端同步场景可能还得上更复杂的架构但对绝大多数业务同步需求来说Dbsyncer这个量级完全够用而且是我国内开源项目中文文档和社区交流都比较友好。2. 部署安装与初始配置2.1 环境准备先说环境。Dbsyncer是用Java写的所以一般需要JRE环境不过它发布的安装包有些是自带运行时环境的能省掉单独装JDK这一步。我建议你看下载包里的说明如果自带JRE直接用就行如果不带就装一个JDK 8或11版本不要太老也不要太新。MySQL这边我用的源库是MySQL 5.7目标库是MySQL 8.0两者版本不一样同步也正常。关于MySQL安装及基础配置网上的教程很多新装环境的话建议直接上MySQL 8.0装完记得确认root能远程登录、防火墙端口放行。磁盘方面Dbsyncer本身占用不大但运行日志和同步元数据会存在本地如果同步任务多、日志量大建议留出几十GB空间别装在根目录快满的机器上。2.2 下载、启动、访问控制台Dbsyncer的安装包在GitHub Releases页面可以下载有两个常用部署方式。解压即用版下载后传到服务器解压到一个固定目录比如/opt/dbsyncer然后进入bin目录执行启动脚本。Linux下是startup.shWindows是startup.bat。启动后控制台默认跑在1860端口浏览器访问http://服务器IP:1860就能打开。Docker部署如果你机器上有Docker拉取镜像后直接跑容器例如docker run -d --name dbsyncer -p 1860:1860 -v /data/dbsyncer:/opt/dbsyncer dbsyncer/dbsyncer注意做目录挂载把数据、日志、配置都挂到宿主机否则容器一删全没了。镜像的具体名称以官方文档为准不同版本可能不一样。第一次打开控制台会让你设置管理员账号密码。这个地方我吃过亏随手设了个简单密码后面同步任务权限和数据源密码都放在这个控制台里密码太弱容易被扫。建议用长密码并且定期改。启动后先到“系统管理”里看看版本信息和日志路径。Dbsyncer的日志文件通常就在安装目录的log文件夹下出问题时这些日志是救命稻草后面排错部分会详细讲。2.3 控制台整体结构Dbsyncer控制台的菜单不算复杂核心就是“数据源管理”和“同步管理”两大块。数据源管理用来维护所有连接信息比如源端MySQL、目标端MySQL每个连接器对应一个库。同步管理则用于创建同步任务选择数据源、映射表、同步模式以及查看同步状态。第一次进去不要急着建任务先把源库和目标库的连接器都配置好连接测试通过再做同步。否则同步任务里选不到可用的数据源会卡住。3. MySQL源端准备先把binlog和账号配好3.1 检查当前MySQL是否开启了binlog增量同步依赖binlog所以这一步是整个增量配置的前提。登录源库MySQL执行以下SQL检查SHOW VARIABLES LIKE log_bin; SHOW BINARY LOGS;如果log_bin的值是OFF或者SHOW BINARY LOGS结果为空说明没开binlog后面增量同步肯定起不来。这种情况下先去改MySQL配置文件。3.2 修改my.cnf启用binlog找到MySQL的配置文件Linux通常在/etc/my.cnf或/etc/mysql/my.cnfWindows通常在MySQL安装目录下的my.ini。在[mysqld]段下添加或修改以下配置[mysqld] server-id100 log-binmysql-bin binlog_formatROW binlog_row_imageFULL expire_logs_days7MySQL 8.0以上版本过期时间参数建议用这个binlog_expire_logs_seconds 604800这里有几个关键点我必须多说几句。server-id一定要设置。MySQL主从复制机制要求每个节点有一个唯一IDDbsyncer作为“伪从库”也会占用一个server-id。如果你机器上还有其他同步工具或者从库记得给它们分配不同值否则会互相冲突导致复制断开。binlog_format必须设置为ROW。这是增量同步的核心。binlog有三种格式STATEMENT、ROW、MIXED。STATEMENT格式记录的是SQL语句同一个UPDATE可能影响多行中间件没法拿到每行变更前后的精确值ROW格式会记录每一行数据的变化包含了before image和after imageDbsyncer才能精确生成对应的INSERT/UPDATE/DELETE语句。所以不设成ROW增量同步很难正常工作。binlog_row_image设为FULL保证binlog里记录完整的前后镜像。有些优化场景会把这个值设为MINIMAL能减少binlog体积但对同步中间件来说拿不到完整行数据可能导致解析异常建议默认FULL。修改完my.cnf后重启MySQL让配置生效systemctl restart mysqld重启后再次执行SHOW MASTER STATUS如果能查到当前binlog文件名和Position就说明binlog已经正常开启。3.3 创建专用同步账号Dbsyncer连接源库不能直接用root也不建议用业务账号最好单独建一个同步账号。这个账号需要能读取需要同步的表并且有复制相关的权限。创建语句大致如下CREATE USER dbsyncer% IDENTIFIED BY 你的强密码; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO dbsyncer%; FLUSH PRIVILEGES;SELECT权限用于全量同步时读取源表数据REPLICATION SLAVE和REPLICATION CLIENT用于增量同步时拉取binlog。如果同步的是多个库这里*.可以换成具体的库名但REPLICATION相关权限本身是全局的直接给.*最省事。目标库账号则需要写入权限。如果只做INSERT/UPDATE/DELETE/SELECT可以这样CREATE USER dbsyncer_target% IDENTIFIED BY 目标库密码; GRANT SELECT, INSERT, UPDATE, DELETE ON 目标库.* TO dbsyncer_target%; FLUSH PRIVILEGES;3.4 目标端表结构准备Dbsyncer做全量同步时会读取源表的数据写入目标表但目标表结构最好是预先建好的。虽然有些版本能自动建表或建映射但自动建表对字段类型、索引、字符集的处理不一定符合你的预期尤其是金额、时间、JSON字段容易出幺蛾子。我的习惯是手动在目标库先建好一张结构一致的表。简单方式是从源库导出表结构在目标库执行一遍。如果字段有调整需求比如目标表增加了冗余字段则在映射关系里手动配置字段对应即可。另外目标表必须有主键或唯一索引否则UPDATE和DELETE定位数据时会很麻烦这一点在增量同步里尤其重要。4. 全量同步配置先把数据对起来4.1 添加源端和目标端数据源打开Dbsyncer控制台进入数据源管理新建数据源。选择MySQL类型填写连接名称、主机、端口、数据库名、用户名、密码。填完先点测试连接确认能连通再保存。有几个细节需要注意。IP最好写内网IP别走公网走公网既慢又不安全。JDBC连接串如果涉及时区问题Dbsyncer界面一般会提供可编辑的连接参数像serverTimezoneAsia/Shanghai这种需要配上否则时间字段可能出现8小时偏差。MySQL 8.0以上版本的驱动依赖Dbsyncer一般内置了不用自己下载驱动老版本可能需要手动上传驱动包。源端和目标端各建一个数据源。如果目标库和源库在同一台MySQL实例上也要拆成两个连接器因为它们的角色不一样。4.2 创建同步任务和表映射在同步管理里新建同步任务。任务名称自己起方便辨识就行比如“orders_main_to_report”。选择源数据源和目标数据源然后进入映射配置。Dbsyncer的映射配置核心是把源表字段和目标表字段对应起来。大多数情况下两边表结构一致可以直接勾选自动生成映射如果两边字段名不一样或者目标表有额外字段就手工调整。这里我建议一个任务只同步一张表或者把关联性强的表放在一起。虽然Dbsyncer支持多表但任务粒度太粗会导致单任务失败时影响面太大排查也不方便。4.3 执行全量同步并验证同步模式选择“全量”保存后启动任务。这时候Dbsyncer会读取源表数据按配置的映射关系写入目标表。数据量不大时几秒就完成了。完成后在目标库验证一下数据量SELECT COUNT(*) FROM 目标库.orders;和源库对比看是否一致。这里有个容易忽略的问题如果源表在同步过程中持续有写入全量同步期间新写入的数据全量任务不一定能抓到。所以“全量同步”更适合在业务低峰期做或者配合增量同步来补这个窗口期的数据这也是下一章的重点。如果目标表之前有旧数据重新跑全量前要考虑是清空重灌还是增量合并。Dbsyncer一般有清理策略或写入模式设置按需选择即可产生的主键冲突问题后面单独讲。5. 增量同步配置核心玩法5.1 增量同步的原理全量同步只是“把数据对齐一次”真正让报表库一直跟上主库节奏的是增量同步。前面说过Dbsyncer增量同步的原理是模拟MySQL从库向源库发送dump请求持续读取binlog。每来一个事务事件它解析出具体行变更然后翻译成目标库能执行的SQL。由于源库的binlog是顺序追加的Dbsyncer只需要记住自己消费到哪个binlog文件的哪个位置就能做到断点续传不会丢也不会重复。这也是为什么源库一定要开binlog、一定要是ROW格式、账号一定要有REPLICATION权限。任何一个条件不满足增量同步都起不来。5.2 配置增量同步任务在同步管理里新建任务源数据源和目标数据源都填好然后映射关系配置好。同步模式选择“增量”。第一次启动增量同步时Dbsyncer需要知道你从哪个binlog位置开始消费。如果全量同步刚跑完应该从全量同步开始的时刻往后消费这样才能补上全量期间产生的数据变更。具体做法是在全量同步开始前先记下源库的binlog文件名和PositionSHOW MASTER STATUS;拿到类似这样的结果File: mysql-bin.000014Position: 542001然后在增量任务的起始位点配置里填写这个文件和Position。这样全量同步先跑增量同步从全量开始那一刻的位点开始追两个任务一配合就能做到数据不丢不多。如果你不想手工填位点也可以在全量任务完成后查看同步任务元数据里记录的位点Dbsyncer有些版本会自动记录。但手工指定始终是最可控的方式尤其适合数据量大的正式环境。5.3 启动增量同步并验证保存并启动增量任务后回到源库执行几条测试语句INSERT INTO orders(order_no, user_id, amount) VALUES(TEST20250101, 1001, 99.90); UPDATE orders SET amount 199.90 WHERE order_no TEST20250101; DELETE FROM orders WHERE order_no TEST20250101;然后去目标库查询这张表正常情况下能看到数据插入、修改、删除都实时同步过来了。Dbsyncer控制台的同步状态页面会展示同步延迟、同步条数、异常事件数。延迟一般应该在秒级甚至毫秒级如果延迟持续上涨就要看是不是目标库写入慢或者网络带宽不够。增量同步启动后不要轻易停任务。如果停了Dbsyncer会记住当前消费位点下次启动会从上次位置继续。但如果停太久源库binlog可能已经过期清理中间的数据就找不回来了。所以binlog保留时间expire_logs_days或binlog_expire_logs_seconds要设置得足够长至少覆盖同步任务最长可能的停机时间。5.4 全量和增量的衔接策略实际生产环境里我比较推荐“先全量后增量”的两段式做法或者直接选Dbsyncer支持的全量增量集成模式。为什么不让增量直接自己跑因为增量同步是从启动那一刻开始消费后续变更它管不了启动之前的历史数据。所以要么先全量把存量数据搬过去再起增量要么先用工具导旧数据再用Dbsyncer追新数据。衔接的关键点就是刚才说的“起始位点”——全量那一刻的binlog位点决定了增量能跟全量无缝拼接。如果业务表数据量特别大全量同步耗时很长期间业务写入也很多可以先做一个“低峰期全量高峰期前起增量”的方案。全量跑完后立刻启动增量尽量缩短时间窗口。如果Dbsyncer的集成模式已经封装好了这套流程直接用更方便但你要理解它内部的位点衔接逻辑出了问题才不慌。6. 实操中踩过的坑与问题排查6.1 常见问题速查表这里把我实际用下来遇到最多的问题整理成一张表遇到可以直接对照。问题现象可能原因解决思路数据源测试连接失败防火墙未放行端口、IP写错、账号密码错误先在服务器上用mysql客户端测试能否远程连接检查网络和账号权限增量任务启动报错提示binlog相关源库未开启binlog或binlog_format不是ROW修改my.cnf开启binlog并重启MySQL确认SHOW VARIABLES LIKE binlog_format结果同步过程中提示server-id冲突机器上其他同步任务或从库占了相同server-id给每个同步任务分配不同server-id增量同步延迟大目标库写入慢、表没有主键导致每条变更全表扫描给目标表建主键/唯一索引调整批量提交大小DELETE和UPDATE不同步源表或目标表没有主键binlog行数据定位失败为源表和目标表设计主键重新做映射关系时间字段少8小时JDBC连接时区不对连接参数加serverTimezoneAsia/Shanghai全量同步重跑时主键冲突目标表已有相同主键数据设置同步策略为清空目标表或覆盖更新增量同步消费位点找不到源库binlog已被清理延长binlog过期时间尽快处理停机问题必要时从当前位点重新全量增量JSON类型或bigint类型数据异常驱动版本老或字段类型兼容问题升级MySQL驱动调整目标表字段类型为对应类型6.2 排查异常的最佳路径遇到同步异常不要一顿乱试。先看Dbsyncer控制台有没有报错再看同步任务的日志。日志一般会精确告诉你哪张表、哪个字段、哪条SQL执行失败了。如果没有明显报错就看同步状态页面的延迟指标和异常事件数。如果是源端的SQL写入报错比如字段长度超了、非空约束冲突那就是目标表结构和源表不一致导致的。这种情况下核对表结构调整目标表字段长度和默认值即可。如果是连接问题先确认源库没有把同步账号的IP限制掉再确认服务器防火墙端口是通的。我遇到过一些场景开发库本地能连服务器上就是连不上最后发现是云安全组没放行。6.3 性能调优的几个方向同步性能方面我没有去压极限但有几个参数实测下来影响很大。第一个是批量提交大小。如果单条INSERT写入目标库速度肯定慢调大批量后吞吐量能翻好几倍。但批量太大也有风险事务太大可能拖慢目标库甚至造成锁竞争建议从500到1000开始试。第二个是同步线程数。Dbsyncer支持多线程并发同步不同的表如果同步几十张表单线程串行会慢得让人着急。把线程数调成和表数量匹配的级别整体速度会明显提升。但线程太多也会增加目标库压力我一般先从4到8开始。第三个是尽量减少无谓的数据转换。映射关系里尽量让源字段和目标字段类型对应不要源端是int、目标端是varchar还塞很长的字符串这种转换最消耗性能。还有一个建议源库和目标库之间的网络延迟越低越好。如果跨地域同步延迟高且不稳定可以先把binlog解析结果投递到中间队列再由目标端消费但这就把架构搞复杂了。对大多数场景内网直连已经足够。6.4 极容易被忽略的隐藏坑有几个隐藏坑我特别想提醒一下。第一源表和目标表的字符集要尽量一致。如果源库是utf8mb4目标库是latin1或utf8特殊字符和emoji同步过去会变成乱码或者报错。建表时就把字符集统一好省得后期叫苦。第二同步账号权限不要追加得太晚。我试过先建了同步任务再去Grant权限结果任务一开始没有权限报错Grant之后还要重启任务才能生效。正确的顺序是先开binlog再建账号授权再做全量任务最后起增量。第三不要在主从环境里把Dbsyncer指向只读的从库玩增量。理论上binlog可以从从库拉但很多从库配置了log_slave_updatesOFF不会记录从主库同步过来的变更你拉不到完整数据。所以增量同步的源最好直接指主库。第四同步任务做完后源库的数据类型变更要谨慎。比如某天你把源表字段从int改成bigint或者改了字段长度Dbsyncer的映射缓存不一定能自动感知。遇到这类变更一般要重启同步任务或者重新生成映射别指望它“自适应”。7. 从实际使用里得到的几点体会这套Dbsyncer配置流程我在几个项目里反复用过算是把全量和增量同步的链路跑顺了。我个人体会最深的一点是全量同步的关键不在“快”而在“稳”增量同步的关键不在“快”而在“准”。全量同步时哪怕慢一点也不要让目标库压力过大增量同步一旦出现位点错乱后面会很被动所以源库binlog保留策略一定要提前规划好。另外有一点同步工具始终是辅助手段它不会帮你解决表结构设计的问题。源表没有主键增量同步的UPDATE和DELETE永远有隐患字段类型乱七八糟同步过去只能是更大的坑。所以用Dbsyncer之前先花时间把表结构理清楚比调任何参数都值。如果你们项目里也有“MySQL数据要同步到另一个MySQL”的需求我建议你按这个顺序走一遍先备份源库表结构建好目标表再开binlog、建同步账号然后用Dbsyncer跑全量最后起增量并验证增删改。整个过程熟练之后半个小时内就能搭好一条同步链路。以后再有人问你“报表库数据怎么刷新”你就不用写定时脚本了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价