迁移MySQL数据库,核心就两条路
两个服务器之间迁移MySQL数据库,最靠谱的方案是逻辑备份(mysqldump)配合管线直传,其次是物理文件冷拷贝,选哪种取决于你的数据量和允许停机的时间。如果你的库在50GB以内,用mysqldump走压缩传输,半小时内基本能搞定,如果数据量上了百GB,直接打包数据文件更快,下面把这套流程掰开揉碎讲清楚。
迁移前必须确认的三件事
动手之前别急着敲命令,先花五分钟确认环境,很多人迁移失败,不是命令错了,是前提没踩对。
- 确认MySQL版本和字符集:源库和目标库的版本不要跨大版本,比如源库是MySQL 5.7,目标库最好也是5.7或8.0,跨版本迁移容易踩排序规则和权限表的坑,用
SELECT VERSION();和SHOW VARIABLES LIKE 'character_set%';分别查一下。 - 确认磁盘空间:目标服务器至少要有源库大小的5倍剩余空间,因为要同时容纳备份文件和导入后的数据。
- 确认网络连通性:用
ping和telnet 目标IP 3306测一下端口通不通,如果跨机房或跨云厂商,确认安全组和防火墙白名单已经放行。
行业共识认为,迁移中最容易翻车的不是数据本身,而是权限和字符集这些”看不见的配置”,花三分钟做一次SHOW GRANTS FOR '用户名'@'主机';,把用户权限一并导出来,到了新服务器直接执行,能省掉后面排查权限报错的大把时间。
mysqldump逻辑备份迁移,适合大部分场景
这是最通用、兼容性最好的一条路,也是几乎所有DBA首选的方法,它的核心思路是:源库导出SQL语句-传到目标库-执行导入,整个过程在一个命令行里就能串联完。
使用方法一:两步走(先导出,再传输)
先在源服务器上导出整个库:
mysqldump -u root -p --single-transaction --routines --triggers --events your_database > your_database.sql
--single-transaction:不加锁,不阻塞线上业务,InnoDB引擎专用,正在跑业务的服务器用这个参数最稳。--routines --triggers --events:把存储过程、触发器、事件一起导出来,缺了这些你迁完会发现自己只搬了壳子。
然后压缩传输,压缩这一步特别关键,文本型SQL文件的压缩率基本在80%以上,能大幅缩短传输时间:
tar -czvf your_database.sql.tar.gz your_database.sql scp your_database.sql.tar.gz root@目标IP:/tmp/
最后到目标服务器上解压并导入:
tar -xzvf your_database.sql.tar.gz mysql -u root -p your_database < your_database.sql
使用方法二:一步到位(管线直传)
不想折腾中间文件,直接把导出和导入串起来,在目标服务器上执行以下命令,从源服务器拉数据:
mysqldump -h 源服务器IP -u root -p --single-transaction --routines --triggers your_database | mysql -u root -p -h 127.0.0.1 your_database
这种方式的优势是不占本机磁盘,数据像水流一样从源库流到目标库,特别适合源库本地磁盘已经告急的场景。
实操里的坑:权限和配置一并迁移
很多教程只迁数据,把账号权限漏了,新服务器上你连接数据库时会发现用户全没了,只能重新创建,更稳妥的做法是把MySQL的mysql库里的user表相关数据也同步处理一下。
简单粗暴的办法:在源库执行mysqldump -u root -p mysql user > user.sql,目标库导入后执行FLUSH PRIVILEGES;。
什么时候必须用mysqldump方案
- 数据库版本跨大版本升级需要调整兼容性
- 只需要迁移部分表,而不是整个实例
- 目标服务器的存储引擎和源库有差异
- 需要保留完整的建表语句和索引定义
整个mysql跨服务器迁移步骤就是这样:check环境 → 导出数据 → 压缩传输 → 导入验证,这套流程你在任何云厂商的文档里都能看到类似的路径,算得上是社区验证过的最稳做法。
数据文件冷拷贝,大数据量迁移最快
如果你的数据量超过100GB,mysqldump导出再导入的效率会让你怀疑人生,逻辑备份的导入过程要逐条执行SQL,回放速度远低于物理拷贝,这时候直接拷贝MySQL的数据文件,是更聪明的选择。
前提条件:版本高度一致
物理文件拷贝要求源库和目标库的MySQL版本尽量完全一致,最好是同一个小版本,跨小版本可能因为文件格式不兼容直接导致库挂掉。
操作步骤
先在源库做干净备份,虽然可以热拷贝,但最稳妥的做法是短暂停止写入业务,保证数据文件一致:
FLUSH TABLES WITH READ LOCK;
然后找到数据目录:
SHOW VARIABLES LIKE 'datadir';
默认情况下输出类似/var/lib/mysql,先用tar打包:
cd /var/lib tar -czvf mysql_data.tar.gz mysql/
把这个包传到目标服务器,注意目标服务器先停掉MySQL服务:
systemctl stop mysqld mv /var/lib/mysql /var/lib/mysql_backup_old tar -xzvf mysql_data.tar.gz -C /var/lib/
重启MySQL前要给数据目录授予正确的权限:
chown -R mysql:mysql /var/lib/mysql systemctl start mysqld
这个方案的优缺点对比
| 对比维度 | mysqldump逻辑备份 | 数据文件冷拷贝 |
|---|---|---|
| 数据量限制 | 50GB以内体验较好 | 百GB以上优势明显 |
| 停机时间 | 不需要锁表,基本零停机 | 需要短暂停写或全程停服 |
| 版本兼容性 | 宽容,可跨版本 | 严格,需同版本 |
| 迁移成功率 | 较高,出错可定位 | 高,但出错难排查 |
业内专家指出,数据量超过200GB的场景下,冷拷贝的linux服务器之间mysql迁移速度通常是逻辑备份的3-5倍,但前提是你能承受那一会儿的写锁定。
可视化工具和第三方方案,适合新手和跨云场景
Navicat迁移
图形界面操作适合不熟悉命令行的朋友,连接两个服务器后直接拖拽数据库即可,但大数据量下不稳定,建议30GB以内的库才用。
MySQL Workbench的Migration Wizard
MySQL官方工具自带迁移向导,支持跨版本、跨平台,能自动做类型映射和语法翻译,但它的执行速度不如命令行,而且对中文注释的兼容性偶尔有瑕疵。
商业云平台的数据传输服务
如果是从本地机房迁到云数据库(比如迁移到简米云RDS或酷番云CDB),云厂商都提供了专用的数据传输工具,会自动处理增量同步和校验,这类工具适合零停机迁移的场景,但会收费,价格按迁移数据量计算。
工具选型的场景建议
- 服务器怎么用mysql数据库迁移最快:数据量小用Navicat拖拽,数据量大用冷拷贝
- mysql迁移需要多长时间:50GB以内用mysqldump约20-40分钟,200GB用冷拷贝约30分钟
迁移后的校验清单,缺一不可
迁移完成不是结束,验证无误才算是真的搬完,按下面这个清单逐项检查:
- 行数对比:在源库和目标库分别执行
SELECT COUNT() FROM关键业务表,进行逐一比对。 - 数据抽样:随机抽几条业务数据的更新时间字段,确认不是旧数据。
- 自增主键值:检查表的
AUTO_INCREMENT值,防止迁移后主键冲突。 - 连接测试:用原账号密码从多个业务主机连接新库,确认权限和网络都通。
- 字符集验证:插入一条中文和emoji的测试数据,确认不乱码。
- 存储过程编译:单独调用一遍迁移过来的存储过程和函数,确认语法兼容。
迁移前后的业务验证,建议在低峰期执行,留出足够的时间窗口,如果数据量特别大,先同步一小部分数据做演练,确认流程无误后再全量执行。
常见问题与排查思路
导入时报错:Unknown collation ‘utf8mb4_0900_ai_ci’
原因:源库版本是MySQL 8.0,目标库是5.7,新版的排序规则在旧版不识别,解决办法是在源库导出时加上参数:
mysqldump --default-character-set=utf8mb4 --skip-set-charset --compatible=mysql40
更稳的办法是把字符集显式改为5.7支持的utf8mb4_general_ci,或者直接将目标库升级到8.0。
目标库有数据,想覆盖怎么办
先确认目标库的数据确实不需要,然后执行:
DROP DATABASE your_database; CREATE DATABASE your_database DEFAULT CHARACTER SET utf8mb4;
再重新导入,避免插入重复主键报错中断。
传输中断了怎么续传
scp传输中断后可以重新传,但MySQL导入过程中断了就麻烦,最实用的办法是导入前用split把大SQL拆分:
split -l 500000 your_database.sql part_
然后逐个导入,哪个part报错就单独排查哪个part,不用全量重来。
迁移时源库业务还在写入,数据不一致
使用--single-transaction参数只能保证导出开始时的一致性快照,如果你迁移期间源库持续有写入,新库会缺失这部分数据,解决思路是:业务切换前再做一次增量同步,或者直接接受一个短的业务停写窗口,在停写期间执行最终的增量导入。
Q&A:关于服务器之间迁移MySQL数据库的常见疑问
云服务器之间迁移MySQL数据库,需不需要买专业工具
不需要,云厂商自带的数据传输服务适合无感迁移,但自建MySQL用mysqldump加scp就够了,如果你的服务器都是同一个云厂商的,用内网传输速度更快,而且不占公网带宽,如果跨云厂商,建议用压缩包方式先传到本机再转发,避免直接跨云走公网的速度瓶颈,选择什么方案取决于你愿意花时间还是愿意花钱。
两个服务器数据库版本不一样,能直接搬吗
可以,但要看版本跨度,MySQL 5.7到8.0是主流可迁移路径,注意字符集和认证插件的差异,MySQL 5.6以下迁移到8.0建议先用mysqldump导出,然后手工修改建表语句中的TYPE和ENGINE关键字,再导入,跨版本最大的坑是加密方式的变更,大概率会遇到认证插件不兼容导致的连接失败。
mysql数据迁移哪个工具好用
工具本身没有好坏,场景决定答案,线下环境用mysqldump最通用,云上实例用官方自带的DTS最省心,本地连远程用Navicat最直观,相比工具的选择,更重要的是先评估你的数据量和停机容忍度,这决定了90%的迁移成败,导出工具选对了,后面基本不会出大问题。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/685809.html





