ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Dbsyncer实战指南:MySQL到MySQL全量与增量同步

Dbsyncer实战指南:MySQL到MySQL全量与增量同步 Dbsyncer这名字我也是在项目群里看人提过几次正好手头有个MySQL同步到MySQL的需求就拿来试了一周。先说结论对于“mysql to mysql 增量、全量”这种最常见的同步场景Dbsyncer能省掉你一大半手工脚本的功夫而且自带管理界面不用写代码就能配完整个流程。这篇文章就围绕它的部署、驱动配置、全量同步、增量同步这四个关键点展开把我的实操过程、参数选择和踩过的坑都整理出来给想用它的人一份能直接照着干的参考。1. 数据同步的选型思路与Dbsyncer的定位1.1 为什么需要数据同步中间件很多团队一开始做数据同步走的是“业务代码双写”或者“定时导数据”的路子。代码双写侵入性太强每个写操作都要多一次网络开销而且在事务里处理不好就容易出现一端成功一端失败的情况排查起来特别痛苦。定时导数据比如凌晨跑个脚本把A库数据刷到B库倒是简单但实时性基本为零业务一旦要求“数据变更后几秒内能看到”这种方式就直接废了。所以就有了基于日志解析的增量同步方案。MySQL把每一次数据变更记录到binlog里同步工具伪装成一个从库去读binlog再解析出增删改操作转发到目标端。这套机制对源库几乎没有侵入不用改业务代码也不会增加事务负担。Dbsyncer走的就是这个路子同时在全量同步这块又做了一层封装把“先全量拉基线、再增量补变化”的常见同步策略合并成了一个可视化配置流程。1.2 Dbsyncer的核心组件与同步机制Dbsyncer是开源的数据同步中间件源码在Gitee和GitHub上都能找到。它主要由这么几块组成管理控制台一个Web界面负责管理数据源、同步器、同步任务和日志。数据源管理统一管理源端和目标端连接目前支持MySQL、Oracle、SqlServer、PostgreSQL等数据库以及Elasticsearch、Kafka等存储。同步器定义“怎么读”和“怎么写”的规则。常见的如表同步器允许你指定源表、目标表、字段映射和过滤条件。任务调度按频率或者手动触发同步任务支持定时同步、增量监听。日志模块记录每次同步的详细日志能看同步速度、错误信息、断点位置。全量同步的机制本质上是JDBC分批查询。控制台按你配置的chunk大小比如每批5000行从源表批量SELECT出来再批量写入目标表。这个过程可以手动触发也可以按cron表达式定时执行。增量同步则完全不同它是通过解析binlog事件流来感知数据变化源库每产生一条INSERT/UPDATE/DELETE目标库就会收到对应的变更操作延迟控制在秒级。1.3 和其他工具的对比什么时候选它说到数据同步中间件大家可能还听过Canal、DataX、Flink CDC这些名字。简单做个横向对比方便你判断场景是否匹配。工具增量同步全量同步界面化管理上手成本Canal强项主打binlog订阅不支持需配合其他工具一般需要自研客户端或连第三方平台中DataX不支持强项离线批量导入无纯命令行中Flink CDC强项支持断点续传支持但需要写Flink作业无需要开发能力高Dbsyncer支持基于binlog支持可视化配置有开箱即用低如果你对实时性要求极高、且团队有Java和Flink开发能力Flink CDC依然是工业级首选。但多数做内部系统、报表库、运营数据平台的团队其实要的就是“几分钟搭好一条同步链路”。Dbsyncer最适合的场景就是不想写代码、不想维护一堆客户端脚本、需要一个界面能看日志和监控、并且同步链路以MySQL为中心。它对标的就是这种轻量级、可视化、可维护的定位。2. 环境准备与部署安装2.1 环境要求一览先把环境要求放在前面免得后面折腾半天发现基础条件不满足。依赖项版本/要求说明JDK1.8及以上Dbsyncer基于Java开发控制台和同步引擎需要JVMMySQL 源端5.6/5.7/8.0必须开启binlog详见2.3MySQL 目标端5.6及以上目标库没有特殊要求建好表即可内存建议2G以上增量任务长时间运行JVM堆外内存占用会涨存储数据目录至少预留几GB用于存内置H2库、日志文件、同步断点等我用的是CentOS 7服务器MySQL 5.7源库、MySQL 5.7目标库JDK 1.8内存4G整个流程跑下来很顺畅。2.2 下载、解压与启动Dbsyncer的安装包在官网和Gitee Releases里都有发布。下载下来是zip或tar.gz包解压后目录结构比较简洁dbsyncer/ ├── bin/ │ └── startup.bat / startup.sh ├── conf/ ├── lib/ └── logs/启动前先确保JDK环境正常java -version启动直接执行cd bin ./startup.shWindows下双击startup.bat即可。启动成功后控制台默认端口是7860浏览器访问http://服务器IP:7860就能打开登录页。默认账号密码通常是admin / admin首次登录后建议立刻修改这属于基本操作。注意bin目录下的脚本会读取conf里的配置来决定运行端口和数据目录具体以你下载版本的实际文档为准。改端口的话找到配置文件里关于端口的内容改掉重启就行。2.3 MySQL源端参数准备关键一步增量同步依赖binlog所以源库必须开启binlog。这是我第一次使用时忽略的环节导致增量任务一直监听不到数据变化。原因是MySQL默认在很多发行版上log_bin是关闭的。开启步骤登录MySQL查看当前binlog配置show variables like log_bin; show variables like binlog_format;如果log_bin是OFF需要修改MySQL配置文件。Linux下通常是/etc/my.cnfWindows下是my.ini。在[mysqld]段添加[mysqld] server-id 100 log_bin mysql-bin binlog_format ROW binlog_row_image FULL expire_logs_days 30逐个解释为什么这几个参数这么重要server-id在复制链路中每个节点必须唯一的标识。Dbsyncer作为伪从库去拉binlog时也需要一个独立server-id不能和源库本身或者其他从库重复。binlog_format ROW只有行级日志才记录了每一行数据变更前后的完整内容。如果是STATEMENT格式记录的是SQL语句本身Dbsyncer解析起来困难而且无法还原字段级变更。binlog_row_image FULL确保binlog里包含变更行的所有列的值。如果设置为MINIMAL只记录需要的列解析时可能拿不到完整镜像目标端更新就无从谈起。expire_logs_days控制binlog保留天数避免文件无限膨胀占用磁盘。对于持续同步的中间件建议保留至少3~7天。修改完重启MySQLservice mysqld restart重启后确认参数生效show variables like binlog_format; show master status;能看到binlog文件名和Position编号就说明一切准备就绪。这一步是整个增量同步的地基。2.4 授权同步账号Dbsyncer读取源库binlog需要复制相关的权限查询数据需要SELECT权限。为安全起见不建议用root账号可以单独建一个用户CREATE USER dbsyncer% IDENTIFIED BY your_password; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO dbsyncer%; FLUSH PRIVILEGES;REPLICATION SLAVE允许这个账号模拟从库进程请求binlog。REPLICATION CLIENT允许查看master状态、binlog文件列表等元数据。SELECT全量同步时需要读源表数据这个权限必不可少。目标库的账号则需要具备INSERT、UPDATE、DELETE以及DDL权限用来执行同步过来的变更。同样建议建专用账号需要建表就额外给CREATE, ALTER, INDEX, DROP。3. MySQL到MySQL全量与增量配置全流程3.1 控制台界面速览登录Dbsyncer控制台后左侧是菜单树核心是“数据源管理”“同步器管理”“任务管理”“系统管理”这几块。第一次进去先别急着建任务先把数据源和同步器这两个基础概念理清。官网及项目文档里有完整的功能说明我这里只讲MySQL to MySQL最常用的操作路径在“数据源管理”里新增两个MySQL连接一个源、一个目标。在“同步器管理”里创建同步规则选择源端表、目标端表以及字段映射。在“任务管理”里创建同步任务绑定同步器设定执行方式全量定时或增量监听。启动任务在“日志管理”里观察同步日志。3.2 数据源配置源端与目标端在控制台进入“数据源管理”点新增。选择MySQL类型需要填写的核心字段如下连接名称自己起一个可识别的名字比如“订单源库-生产”“订单目标库-报表”。IP地址和端口源库和目标库分别填自己环境的地址。数据库名默认连接的database后续同步器会基于这个库选择表。用户名和密码刚创建的专用账号。驱动选项连接池大小、超时时间、测试SQL等新手保持默认即可。填完后点“测试连接”能通就说明基本没问题。这里有一个我踩过的坑如果源库和小目标库在公网环境下且开启了SSLDbsyncer连接参数可能需要额外配置SSL相关项否则会报类似“SSL connection error”的错。报错时优先检查驱动版本和连接串参数图片化的配置在界面上没有太多高级项需要根据日志提示手动确认。3.3 全量同步创建同步器同步器是Dbsyncer里比较核心的概念。做一个全量同步要确定“数据从哪里来”“目标写到哪”“字段怎么对”。操作步骤如下步骤1新建同步器在“同步器管理”点新增选择“表同步器”类型。界面会让你选择源端数据源和目标端数据源就是刚才配好的两个连接。步骤2选择源表和目标表源端选择你要同步的具体表比如orders目标端选择目标库中接收数据的表比如ods_orders。这里要注意如果目标表不存在你需要先在目标库建好或者在Dbsyncer提供的DDL功能中执行建表语句视版本而定并非所有版本都内置自动建表。步骤3配置字段映射与过滤条件字段映射是默认自动进行的同名同类型的字段会匹配上。如果源表和目标表字段名不一致逐一手工选对应关系。Dbsyncer还支持配置过滤条件即只同步满足条件的数据。例如只同步最近7天的订单order_time DATE_SUB(NOW(), INTERVAL 7 DAY)这个过滤条件会拼接到全量SELECT语句中减少传输量。步骤4设置批次大小全量同步最关键的一个参数是“批次读取大小”英文一般叫Chunk Size。这个值决定了一次从源表取多少行、再一次性写多少行。取值偏小同步速度慢取值偏大源库和中间件内存压力大。经验值数据量建议Chunk Size10万行以下2000~500010万~500万5000~10000500万以上10000~20000实际上管道内的RAM是主要瓶颈建议小规模先跑个几千试试观察日志中的同步速度再做调整。3.4 全量同步创建并启动任务同步器配置好以后进入“任务管理”新建任务关联刚创建的同步器。执行类型选择“定时任务”或“立即执行”。如果是线上首次同步先跑一次全量把数据基线建起来。点启动后任务队列会开始处理在“日志管理”里能看到同步的实时状态包括已读取行数、已写入行数、累计耗时。我在一个700万行的订单表上跑过一次全量Chunk Size设成10000耗时大约38秒速度比较可观。主要瓶颈是MySQL的SELECT和INSERT往返中间件的处理反而很快。全量任务结束以后重点做数据校验。简单的方式就是在源库和目标库分别执行select count(*) from orders; select count(*) from ods_orders;数量对得上再抽样看几条关键字段内容。如果数量不一致优先检查同步日志里是否跳过了一些脏数据比如目标表字段长度限制导致插入失败。3.5 增量同步配置 binlog 监听全量同步只是把“当前时刻”的数据复制过去真正让数据保持连续同步的是增量同步。增量同步对同步器的要求不同它不依赖表同步器里的SELECT逻辑而是依赖binlog解析。操作路径如下在“同步器管理”中新建一个增量监听相关的同步器不同版本界面名称略有差异有的叫“日志同步器”选择目标数据源以及你要消费的binlog位点。如果之前已经跑过全量那么增量的起点应该从“全量同步完成的那个时刻”开始这样不会丢数据也不会重复。然后在“任务管理”创建增量任务绑定这个同步器启动。Dbsyncer连接源库的MySQL后会开始接收binlog事件识别出orders表上的INSERT、UPDATE、DELETE操作并转换为目标库的SQL执行。为了验证增量是否生效我在源库执行了一条简单UPDATEupdate orders set status PAID where id 1001;过了几秒钟目标库的同一条记录也随之变化了。再执行INSERT和DELETE同样能看到目标库同步更新。日志中会显示类似“处理binlog 位置 xxx, 事件类型 UPDATE”的信息。3.6 全量增量如何组合实际生产环境最稳妥的组合是先做一次全量等全量任务跑完立刻启动增量任务并且把增量任务的起点设置成全量任务结束时的binlog位点。Dbsyncer在内部其实维护了一个发布订阅机制增量任务的启动位置可以通过日志界面的binlog位点信息来确认。做法是全量任务执行前记录源库当前的binlog文件名和Positionshow master status;全量任务跑完后记录此刻的binlog文件名和Position。创建增量任务时将开始位点设置成第2步记录的值。这样就能做到全量同步期间产生的数据变更不遗漏。如果Dbsyncer的增量任务支持自动从“当前暂停位置”续跑那么更省事——先把增量任务停了做全量全量完成后再启动增量任务它会自动从停掉时的位点继续消费。注意全量同步过程中源表数据一直在变化。如果全量跑了很长时间增量任务没启动的情况下这期间的新增数据可能被全量的快照覆盖或漏掉。最安全的方式就是在业务低峰期操作并确保全量结束时间和增量启动时间之差越小越好。4. 常见问题排查、参数调优与实操心得4.1 我遇到过的几个典型问题问题一测试连接一直失败报“Access denied for user”这个大概率是权限没给全或者账号只允许了特定host登录。检查授权语句是否为dbsyncer%以及MySQL是否刷新了权限。还有一种情况是密码中有特殊字符在连接串里没有正确编码。我后来干脆把密码改成纯字母数字组合省心不少。问题二增量任务日志提示“binlog not found”有两种可能一是binlog文件已被清理比如源库设置了expire_logs_days而你增量任务停止的时间超过了保留天数二是binlog位点不连续Dbsyncer找不到指定文件。解决办法是把增量任务起点重新设为MySQL当前最新位点。缺点是这样会丢失暂停期间的数据变更所以线上环境如果暂停增量超过保留期限就必须通过重跑全量来补偿数据。问题三同步到目标端的UPDATE不生效我遇到过目标表有主键但源表同步过来时主键映射没有配置的情况。如果MySQL binlog格式是ROW且row_image是全量那INSERT一般没问题但UPDATE没有主键定位时会走全表更新或者被过滤。解决办法是检查同步器的字段映射确保目标表的唯一键/主键字段和源表对应。尤其是在跨库同步时主键字段名如果两边不一致必须在映射里显式配置。问题四同步任务出现OOM或内存飙升Dbsyncer本身是Java进程JVM堆内存设置不当或者Chunk Size太大会造成频繁Full GC甚至OutOfMemoryError。在启动脚本里可以调整JVM参数比如把堆内存调大到1G或2GJAVA_OPTS-Xms512m -Xmx2048m同时缩小全量同步的批次大小。增量同步的数据流是持续性的内存当中需要维护一定数量的缓冲区如果目标库写入速度跟不上缓冲区会积压所以还得看目标库是否有慢SQL或锁竞争。4.2 常见问题速查表现象可能原因解决方向连接源库失败账号权限不足、网络不通、驱动不匹配检查授权和网络确认驱动版本全量同步速度慢Chunk Size偏小、源库磁盘IO压力大调大Chunk业务低峰期执行增量任务不消费数据binlog未开启、位点有误、server-id冲突检查log_bin配置核对位点改server-id目标端数据缺失字段映射不全、过滤条件过严、脏数据报错跳过查看错误日志完善映射放宽过滤内存溢出JVM堆过小、Chunk过大调整JVM参数降低批次大小同步延迟持续增大目标库写入慢、大事务产生大量binlog排查目标库锁和SQL性能考虑拆表同步4.3 关于参数调优的几个经验全量同步最值得调的参数就是Chunk Size和JDBC连接的超时时间。Chunk Size不是越大越快过大的时候MySQL驱动会把所有结果缓存在内存中再交给中间件反而增加GC压力。比较合理的方式是先跑一小段数据量观察耗时再动态调整。增量同步的核心参数是“批量应用大小”或者说“异步提交间隔”。Dbsyncer可以从binlog里一次解析出很多变更事件然后批量执行到目标端。如果目标端是MySQL批量能显著提升吞吐量。比如每秒大量UPDATE短事务的情况下逐条执行和批量执行的能力差距可能在一倍以上。我调大后同步延迟从几十秒降到几秒。另一个容易被忽略的点是目标库表结构。如果目标库的表没有主键那么UPDATE和DELETE同步时定位记录的成本会很高因为MySQL需要逐行扫描匹配。建议目标表保留和源表一样的主键或者至少建一个唯一索引。4.4 数据一致性校验方法同步链路搭好了如何证明数据没问题除了简单的count比对还可以做更细致的校验抽样校验在源表和目标表中各取主键相同的若干行对比关键业务字段是否一致。可以写个简单的SQL脚本对比MD5。增量时间戳校验在源表中增加一个update_time字段每次变更自动更新目标表在相同条件下也记录同步到达时间。通过对比源表最新更新时间与目标表同步时间判断延迟是否在可接受范围。反向核查在目标库随机选几条记录去源库对比。这种方法对DELETE场景尤其有效因为目标库多出来的数据就是同步异常的重要线索。我自己常写一个简单的校验脚本逻辑是从源表按主键分页拉取一批数据的MD5再在目标表按同样主键拉取对应数据比对两组MD5是否一致。具体脚本不算复杂但很实用。建议把这个脚本保留下来每次同步配置变更后都跑一次。4.5 关于增量任务长期运行的维护心得增量任务一旦配置好它会像守护进程一样7x24小时运行此时最怕的是源库binlog文件清理策略配置不合理。前面已经说过expire_logs_days如果设得太短中间件故障恢复后它会找不到历史binlog只能重做全量。这里强烈建议把binlog保留时间调长一点比如7天以上并配合监控告警及时发现同步中断。另外Dbsyncer会把自己记录的消费位点持久化下来正常情况下重启中间件任务会自动从上次的位点继续同步。但如果你在维护过程中手动修正过MySQL的binlog位点比如做过从库重建两个位点之间可能就衔接不上这时最好是手动重置增量任务起点或重新跑一遍全量。根据我个人经验在一个稳定运行的同步系统里全量与增量相结合能覆盖大多数实际需求——全量负责打底增量负责兜底。Dbsyncer这个中间件的价值在配置化和日志可视化上体现得最明显遇到数据问题能快速回放日志定位这一点比写一堆Python脚本手工维护要省心得多。如果你后续需要对接Elasticsearch或者Kafka可以在现有基础上继续扩展同步器就能实现方向是相通的。
返回列表