在大规模MySQL数据库迁移场景里,mydumper与myloader是经常被提到的组合。它们最早由DBA团队开发,目标就是解决mysqldump在逻辑备份时单线程效率低下的问题。mysqldump虽然简单可靠,但导出上亿行数据时往往要花费几个小时,甚至因为长时间持有锁影响业务。mydumper通过将一个库拆分成多个表,甚至将单个大表按主键范围拆分成多个数据块,让多个工作线程同时执行SELECT导出,再配合一致性快照,既保证了数据在某个时间点的一致性,又能成倍提升导出速度。恢复时myloader会并行读取这些拆分好的文件,把数据批量加载回目标实例。

一、mydumper/myloader 与传统工具的核心差异
mysqldump的导出逻辑可以理解为一条SQL接着一条SQL地生成文本,即使开启--single-transaction,数据读取仍然局限于单个连接、单个线程。对于包含数百张表、单表数千万行的数据库,这种串行方式会严重浪费服务器的多核CPU和存储带宽。mydumper改变了这个模型:它首先建立一个连接用于创建一致性快照,然后根据--threads参数启动多个工作连接,每个工作线程负责一部分表或者某个表的某个数据块。这些工作线程在一致性快照下读取数据,因此不会产生幻读或重复行。最终导出目录下会出现每个表对应的数据文件,例如testdb.users.sql、testdb.orders.00001.sql等,这种拆分方式也为后续并行导入提供了天然基础。
与物理备份工具Xtrabackup相比,mydumper的逻辑备份可以跨版本、跨平台恢复,也支持只恢复某一个库或某几张表,灵活性更高。Xtrabackup在物理层面复制数据页,速度非常快,但要求源端和目标端的MySQL版本、存储引擎甚至操作系统兼容,而且恢复时通常需要整个实例一起恢复。mydumper刚好弥补了这种不足,在需要做库表级重组、异构迁移或从MySQL迁移到MariaDB、Percona Server等场景中非常实用。虽然逻辑备份整体速度不如物理备份,但在并行能力的加持下,多数情况下已经能满足几十GB到几百GB库的快速搬迁要求。
另一个重要差异体现在导出文件的管理上。mysqldump生成一个巨大的SQL文件,恢复时无法并行,而且一旦文件损坏几乎无法挽救。mydumper将不同表甚至同一张表的不同分块拆成多个独立文件,恢复时可以按需选择、并行加载,也可以先恢复核心表再恢复次要表,甚至能在恢复过程中通过文件列表检查进度。
二、安装与基础命令演示
在常见Linux发行版上安装mydumper/myloader比较简单。Ubuntu或Debian系统可以直接使用apt install mydumper,CentOS或RHEL可以通过EPEL仓库安装,也可以从GitHub下载预编译二进制。安装完成后执行mydumper --version确认版本,建议使用0.12以上的稳定版本,因为早期版本在--rows分块和一致性处理上有一些已知问题。
下面演示一次完整备份操作。假设源数据库有一个名为testdb的库,导出目录为/data/backup,使用8个线程,开启一致性快照,同时将每个大表按500000行分块,并对输出文件进行gzip压缩。命令如下:
mydumper -u root -p 'YourPassword' -h 127.0.0.1 -P 3306 \ -B testdb -o /data/backup -t 8 \ --trx-consistency-only --rows 500000 \ --compress --build-empty-files
执行后,进入/data/backup目录可以看到类似下面的文件结构:metadata存放开始和结束的一致性位置,testdb-schema-create.sql用于创建数据库,testdb.users-schema.sql存放表结构,testdb.users.00001.sql.gz等是实际数据文件。这种清晰的划分使得后续管理非常方便。
恢复数据时使用配套的myloader,指定备份目录、目标连接、线程数。如果目标库已经存在同名表,可以用--overwrite-tables覆盖;如果希望先删除再重建,可以加上--drop-first。一个典型的导入命令如下:
myloader -u root -p 'TargetPassword' -h 192.168.0.2 -P 3306 \ -d /data/backup -t 12 --overwrite-tables
在导入过程中,myloader会读取备份目录中的每个数据文件,分配给不同的线程并行执行LOAD DATA或INSERT操作。默认情况下,它优先使用LOAD DATA LOCAL INFILE快速加载,如果目标端配置不允许则会退化到普通插入。为了保证大量数据导入时的效率,建议目标实例的max_allowed_packet调大,避免单个批次数据包被拒绝。
三、并行迁移实战:过滤、分块与一致性
现实中的迁移很少是全库无条件搬迁,往往只需要同步部分表,或者需要将超大表拆得更细。mydumper提供了强大的过滤能力,例如--regex可以按正则表达式匹配表名。假设只想导出testdb库中所有以order_开头的表,可以使用:
mydumper -u root -p 'YourPassword' -B testdb \ --regex '^(testdb\.order_)' -o /data/orders_backup -t 6 \ --trx-consistency-only --compress
对于单表数据量特别大的情况,可以在全局参数中使用--rows指定块大小,也可以针对某张表单独设置,例如--tables-list配合--rows=200000,把一张千万行的表拆成几十个文件并行导出。这种分块策略同样适用于带自增主键或可比较主键的表,mydumper会根据主键范围划分数据块,避免单线程处理过多数据。
一致性是逻辑备份必须重视的问题。--trx-consistency-only适用于InnoDB表,它只使用一个事务来读取所有表,导出期间其他事务可以继续修改数据,不会锁表。但如果库中包含MyISAM等非事务引擎,就需要使用--lock-all-tables全局读锁来保证一致性,这会阻塞写入,只能在低峰期执行。实际生产环境建议尽量将表全部转换为InnoDB,以便利用快照一致性,减少对业务的影响。
跨机器搬迁时,通常先将备份目录压缩打包,再通过rsync或scp传输到目标服务器。如果源端和目标端网络带宽有限,可以在mydumper导出时直接使用--compress-protocol压缩客户端与服务器的通信,或先导出压缩文件再传输。下面是一个完整的远程迁移示例:
# 在源服务器导出 mydumper -u root -p 'SourcePass' -B ecommerce -o /data/ecom_backup \ -t 16 --rows 300000 --trx-consistency-only --compress # 打包并传输 tar -czf ecom_backup.tar.gz -C /data ecom_backup scp ecom_backup.tar.gz user@目标服务器:/data/ # 在目标服务器解压并导入 tar -xzf /data/ecom_backup.tar.gz -C /data myloader -u root -p 'TargetPass' -h localhost -d /data/ecom_backup \ -t 16 --overwrite-tables
该示例展示了从导出、压缩传输到恢复的完整链路。需要特别注意的是,如果备份文件中包含存储过程或触发器,myloader默认不会创建它们,需要显式加上--enable-routines或--enable-triggers参数。外键约束也可能导致导入顺序问题,通常在导入前先通过SET FOREIGN_KEY_CHECKS=0关闭约束,导入完成后再开启,可以用myloader的--skip-definer避免权限定义冲突。
四、性能调优与避坑指南
并行数量并不是越大越好。mydumper和myloader的线程数设置需要和源端、目标端的CPU核心数、磁盘IO能力以及网络带宽匹配。如果线程开得过多,反而会引发大量随机IO和上下文切换,导致整体性能下降。经验上,导出线程数可以设置为CPU核心数的1到2倍,但不要超过磁盘能够承受的并发读队列深度。可以通过监控iostat和vmstat观察磁盘利用率,如果util长时间接近100%,说明已经到达硬件瓶颈,此时增加线程没有意义。
压缩选项会显著影响导出速度和文件大小。--compress会对每个输出文件进行gzip压缩,在CPU足够的情况下可以节省大量磁盘空间,并且后续传输更快,但代价是导出过程中消耗更多CPU。如果不希望压缩文件,但又想降低网络传输量,可以结合--compress-protocol使用,它只压缩数据库连接上的数据流,不产生压缩文件。对于万兆内网环境,不压缩直接导出通常更快,因为压缩和解压本身有开销。
另一个常见的坑是字符集。如果源库和目标库的默认字符集不一致,导入后可能出现中文乱码。mydumper和myloader都支持--default-character-set参数,建议在导出和导入时都显式指定与库一致的字符集,例如utf8mb4。此外,迁移完成后务必进行数据校验,可以通过CHECKSUM TABLE对比源和目标的关键表校验和,或者使用pt-table-checksum对行级数据做更精细的比对。
最后要提醒的是,如果源库存在长时间未提交的事务,即使使用一致性快照,也可能导致undo日志快速膨胀,进而影响导出稳定性。因此在执行大规模导出前,最好检查information_schema.innodb_trx中的长事务,并在业务低峰期操作。对于在线核心库,建议先在从库上做备份,避开主库压力。通过合理规划线程、压缩、分块和传输策略,mydumper/myloader完全可以把原本需要数小时的搬迁压缩到几十分钟,真正实现极速搬迁。