跨地区mysql迁移应避免本地落盘,直接用mysqldump | gzip | ssh管道传输,并调大max_allowed_packet、net_buffer_length等参数,启用mydumper多线程可大幅提升效率。

用 mysqldump 加压缩管道直接传,别先写本地文件
跨地区迁移最卡的不是 dump 本身,而是把几 GB 的 SQL 文件先落地磁盘、再上传——多一次 I/O + 多一次网络传输。直接用管道让 mysqldump 输出流进 gzip 再走 ssh,能省一半时间。
- 本地不落盘:
mysqldump -h old-host --single-transaction --routines --triggers db_name | gzip | ssh user@new-host "gunzip | mysql -h localhost db_name" - 加
--single-transaction避免锁表,但只对 InnoDB 有效;MyISAM 必须停写或用--lock-all-tables - 如果网络丢包高,
ssh默认 TCP 缓冲小,加-o "TCPKeepAlive=yes" -o "ServerAliveInterval=30"防断连 - 别用
pv测速时加在管道中间(比如mysqldump | pv | gzip),它会成为瓶颈;要测就用pv -b放最后:... | gunzip | pv -b | mysql
max_allowed_packet 和 net_buffer_length 必须两边同步调大
跨地区链路延迟高,小包频繁 ACK 会拖慢吞吐;而默认 max_allowed_packet=4M 在导入大 BLOB 或长文本时直接报错 MySQL server has gone away。
- 在源库和目标库的
my.cnf里都设:max_allowed_packet = 512M,net_buffer_length = 1M - 目标库还要确认
innodb_log_file_size足够,否则大批量 INSERT 会触发频繁 checkpoint,IO 拉满 - 如果用
mysql客户端导入,它也有自己的max_allowed_packet,启动时加参数:mysql --max-allowed-packet=512M
跳过非必要日志与约束,但得清楚代价
关日志和约束能提速 3–5 倍,但不是所有场景都安全——尤其目标库还在提供读服务,或后续要主从同步。
- 导入前在目标库执行:
SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0; SET AUTOCOMMIT = 0; - 关 binlog(仅限单次迁移):
SET sql_log_bin = 0;,否则主从延迟爆炸,且可能因 GTID 冲突失败 - 别关
innodb_flush_log_at_trx_commit—— 这是持久性开关,关了等于迁完数据但机器一崩全丢 - 导入完必须立刻恢复:
SET FOREIGN_KEY_CHECKS = 1;,然后手动CHECK TABLE验证外键一致性
用 mydumper 替代 mysqldump,特别是大库分表场景
mysqldump 是单线程,100GB 库跑通要十几小时;mydumper 支持多表并行 dump + 自动分 chunk,对 SSD 和千兆以上带宽更友好。
- 安装后直接:
mydumper -h old-host -u user -p pass -B db_name -o /tmp/dump/ --compress --threads 8 - 注意
--compress是 client 端压缩,不是网络压缩;想压网络得配ssh -C或走rsync --compress - 恢复用
myloader,它会自动按表并发导入,但要求目标库已建好空库,且字符集一致,否则报Unknown character set - 如果表里有 JSON 字段或 8.0 新特性,确认
mydumper版本 ≥ 0.11.1,老版本会丢精度
net_buffer_length 默认值、SSH TCP 参数、或者你忘了 myloader 不自动建库这回事。











