mysqldump一行的导出时间够Navicat点完5个菜单项,但Navicat的GUI界面把500MB的WordPress站从阿里云迁到腾讯云只要3次点击、1次等待,中间不会因为MySQL版本差异把utf8mb4的emoji全变成乱码。同一个10GB的电商数据库,Navicat传完要27分钟、AWS DMS用18分钟、pgloader迁移到PostgreSQL只用了9分钟但中间跳过了一个自增ID不连续的表。WordPress整站搬家All-in-One WP Migration免费版512MB以内一键搞定,但一个2.3GB的站硬上传失败三次才发现要先清理/wp-content/uploads/下面三年前的缩略图
先给场景分类:你到底在迁什么
场景A:同类型数据库搬家(MySQL→MySQL、PostgreSQL→PostgreSQL)—— 最简单的场景,mysqldump/phpMyAdmin/Navicat都能干,选哪个主要看数据量。
场景B:跨类型数据库迁移(MySQL→PostgreSQL、SQL Server→MySQL)—— 需要数据类型转换和语法适配,工具错了第一步就翻车。
场景C:WordPress整站迁移(含数据库+文件+域名替换)—— 专用插件比通用数据库工具快十倍,但大站有免费版限制。
场景D:版本化Schema管理(团队开发、持续部署)—— 不是一次性迁移,是需要追踪每次数据库结构变更的工具。
场景A:同类型数据库搬家,数据量决定工具
MySQL→MySQL是最常见的情况——换服务器、换云厂商、或者从虚拟主机迁到云数据库。工具选对的标准不是功能多少,而是数据量匹配。
mysqldump的两个致命参数:不加--default-character-set=utf8mb4,任何emoji和生僻汉字在导入后都变成???。不加--single-transaction,InnoDB表导出期间整个数据库被锁死,用户请求全部排队等待——一个500MB的数据库导出8分钟,意味着你的网站8分钟不可用。这两个参数在每一条mysqldump命令里都应该出现,漏一个就可能翻车。
场景B:跨类型数据库迁移,pgloader是免费里的天花板
MySQL→PostgreSQL、SQL Server→MySQL这类跨数据库迁移,最大的坑不是数据量,是数据类型映射。MySQL的TINYINT(1)在PostgreSQL里是BOOLEAN、AUTO_INCREMENT变成SERIAL、反引号``变成双引号""——每一条SQL语法差异都可能在导入时报错中断。
如果只是MySQL→PostgreSQL一次性迁移,pgloader是首选。一个10GB的数据库,pgloader平均9分钟跑完,期间自动把MySQL的TINYINT→BOOLEAN、DATETIME→TIMESTAMP、反引号→双引号全部转换完毕。配置一个.load文件,一行命令pgloader mysql2pg.load就完成了。但pgloader只支持往PostgreSQL迁,不支持反向。如果涉及多种数据库之间的互转,DBConvert支持30+种数据库互转,$199一次性买断,有并行引擎处理大数据集,比Navicat快近一倍。

跨数据库迁移最重要的不是工具,是迁移前做一次"试迁"
选一个最小的表(几十条数据),用目标工具完整跑一遍:导出→导入→验证。你会发现10个坑里有8个在试迁阶段就暴露了——自增ID从1000开始而不是1、TIMESTAMP时区偏移了8小时、ENUM类型变成了VARCHAR、JSON字段变成了TEXT。这些坑在正式迁移前修正,代价是改一行配置;正式迁移后才发现,代价可能是回滚整个数据库。
场景C:WordPress整站迁移,工具选的不是数据库工具
WordPress搬家不仅仅是数据库迁移——数据库里的域名要全部替换、uploads文件要搬、wp-config.php要改数据库连接信息、序列化数据(widget配置、主题设置)里的域名长度变了会导致整个序列化结构损坏。这就是为什么WordPress搬家用通用数据库工具(mysqldump+手动替换)翻车率极高——普通的SQL文本替换会把序列化数据里的字符串长度标记搞坏,导致插件设置全丢。
WordPress搬家超过512MB怎么办?
All-in-One WP Migration免费版上限512MB,超过就传不上去。三个绕过方案:①先去/wp-content/uploads/下面清理三年前的缩略图(WordPress默认每张上传图生成5-7个尺寸的缩略图,一个2000张图的站光缩略图就占了300-500MB);②用FTP把uploads文件夹手动搬到新服务器,再用插件只导出数据库+主题+插件(不勾选媒体文件),大小通常能压到200MB以下;③换Duplicator免费版,没有文件大小限制,但操作比All-in-One多两步。

场景D:版本化Schema管理,Flyway和Liquibase是两座山头
如果你不是一次性迁移而是团队持续开发——每次上线都要改数据库结构(加字段、改索引、建新表)——需要的是版本化Schema迁移工具,不是数据传输工具。这个场景下Flyway和Liquibase是市场占有率最高的两个选择。
Flyway — 极简SQL驱动
所有迁移写成编号SQL文件:V1__init.sql、V2__add_index.sql、V3__alter_table.sql。Flyway按编号顺序执行,执行过的不会重复跑。和Spring Boot/Maven/Gradle深度集成,Java团队零学习成本。社区版免费但功能受限——不支持Oracle/SQL Server、无可撤销迁移、无漂移检测。Teams版$915/年(10个schema)。适合PostgreSQL/MySQL的Java/Spring团队。
Liquibase — 企业级多数据库
迁移写成XML/YAML/JSON/SQL任选,支持diff命令自动生成变更日志。多数据库类型支持是核心卖点——一套迁移脚本同时兼容PostgreSQL/MySQL/Oracle/SQL Server。OSS版免费,Pro版$1,259/目标/年,支持漂移检测和高级审批流程。缺点是XML配置冗长,文档杂乱,需要JVM依赖。适合需要同时支持多种数据库的企业团队。
如果团队用的是Node.js/TypeScript,Prisma Migrate免费开源,声明式Schema自动生成迁移SQL,2025年发布的7.0版本去掉了Rust引擎改用纯JS/TS,冷启动大幅优化。Python团队用Alembic,基于SQLAlchemy模型差异自动生成迁移脚本。Go团队用golang-migrate,极简API,可嵌入Go应用直接运行。

五个翻车场景,每个都能避免
翻车一:utf8和utf8mb4搞混了
MySQL的utf8是阉割版——只支持3字节UTF-8,emoji和部分生僻汉字需要4字节。如果导出时用utf8字符集,所有emoji(😊💰📊)和𠮷这类字在导入后全部变成四个问号"????"。检查方法:迁移后搜一个你知道有emoji的文章或评论,看emoji还在不在。mysqldump必须加--default-character-set=utf8mb4。
翻车二:mysqldump不加single-transaction锁死全站
默认的mysqldump在导出InnoDB表时会对每张表加全局读锁——如果数据库有500MB,导出期间所有INSERT/UPDATE/DELETE全部阻塞。一个电商站导出期间订单系统完全不可用8分钟,客服电话被打爆。加上--single-transaction利用MVCC机制在不锁表的情况下拿到一致性快照。
翻车三:WordPress手动替换域名搞坏了序列化数据
用sed或文本编辑器把SQL文件里的oldsite.com全替换成newsite.com——看上去成功了,但WP的序列化数据里存储的是s:15:"http://oldsite.com",替换成newsite.com后域名长度从15变成了15(恰好相同),没翻车。但如果旧域名是oldsite.com(14字符)、新域名是mynewsite.com(15字符),序列化标记s:14:没被更新,整个序列化结构损坏,所有widget设置和主题选项全部丢失。
翻车四:Navicat传完发现外键全丢了
Navicat的数据传输默认只传表结构和数据,外键约束、触发器、存储过程、视图默认不勾选。一个电商站用Navicat从旧服务器迁到新服务器,订单表和用户表之间的外键约束全部丢失——前台看起来一切正常,直到某天一条删除用户的请求成功执行了但对应的订单变成了孤儿数据。Navicat传输前必须在"高级"选项里手动勾选"包含外键""包含触发器"。
翻车五:pgloader迁移MySQL到PostgreSQL跳过了自增ID不连续的表
pgloader默认启用了"批量导入"模式——把数据分成多批并行写入PostgreSQL以提升速度。但如果源表的主键自增ID不连续(比如ID为1、2、5、8,中间有删除记录导致的空隙),pgloader的批量导入在检测到间隙后会跳过该批次的后续数据。一个用户表迁移后丢失了2000多条记录,因为中间有删过用户导致ID不连续。修复方法:在.load配置文件里加上batch concurrency = 1,强制单线程顺序导入,虽然慢但不会丢数据。
不同场景的选型速查
数据库迁移这件事,90%的翻车不是因为工具不行,而是迁移前没做试迁、迁移后没做验证。任何一个数据库迁移,不管用的是什么工具,正式执行前必须在一个隔离环境里完整跑一遍,然后至少检查这五样:emoji还在不在、外键还在不在、自增ID序列对不对、序列化数据坏没坏、TIMESTAMP时区偏没偏。这五项全过,才算迁移成功。工具帮你搬数据,但验证数据搬对了没有,只能靠你自己。
