真正省带宽的做法是让数据从 MySQL 内存直出 → 压缩 → 加密 → 解压 → 导入,全程不碰磁盘;正确命令为 mysqldump -u root -p --single-transaction db_name | gzip -3 | ssh user@host "gunzip | mysql -u root -p db_name"。

直接管道压缩,别落地再传
本地先写 dump.sql 再 scp 上传,等于同一份数据读磁盘、写磁盘、走网络三轮,带宽被重复占用。真正省带宽的做法是让数据从 MySQL 内存直出 → 压缩 → 加密 → 解压 → 导入,全程不碰磁盘。
- 正确命令:
mysqldump -u root -p --single-transaction db_name | gzip -3 | ssh user@host "gunzip | mysql -u root -p db_name" -
--single-transaction对 InnoDB 有效,避免锁表;MyISAM 表必须换--lock-all-tables - 别加
--skip-extended-insert:它会让每行一个INSERT,SQL 体积翻倍,反而更耗带宽 - 压缩用
gzip -3而非-9:10 GB dump 用-9多花 72 秒,只少 200 MB,纯属 CPU 浪费
大库必须分片 + rsync 断点续传
单管道扛不住百 GB 级迁移:ssh 超时、MySQL 连接闪断、目标磁盘满,都会导致重来。这不是网络问题,是传输模型本身不可靠。
- 按表导出:
mysqldump -u root -p db_name --tables t1 t2 | gzip > part1.sql.gz - 立刻用
rsync -avz --partial --progress推送:断了不删已传部分,下次续传剩余字节 - 目标端导入前务必校验:
ssh user@host "md5sum /backup/part1.sql.gz",和本地比对 - 别依赖
pv测速放管道中间(如mysqldump | pv | gzip),它会成瓶颈;真要监控,放最后:| gunzip | pv -b | mysql
参数不调大,管道必断
默认 max_allowed_packet = 4M 是管道失败的头号原因——BLOB 或长文本还没发完,目标端就报 MySQL server has gone away。
- 源库和目标库的
my.cnf都要改:max_allowed_packet = 512M、net_buffer_length = 1M - 客户端导入也要显式指定:
mysql --max-allowed-packet=512M -h localhost db_name - 目标库还得检查
innodb_log_file_size:太小会导致大批量INSERT触发频繁 checkpoint,IO 拉满,表面像网络慢,实际是磁盘堵死 - 跨地区链路 RTT 高时,内核 TCP 参数也得调:
net.ipv4.tcp_rmem = 4096 262144 16777216,否则 ssh 会频繁重传、吞吐骤降
mydumper 比 mysqldump 更适合并发迁移
mysqldump 是单线程,100 张表只能串行扫;mydumper 可开多线程同时 dump 多张表,CPU 和网络更均衡,总耗时明显下降。
- 命令示例:
mydumper -u root -p pass -B db_name -o /backup/ -t 4 --compress(-t 4开 4 线程) - 生成的是
schema.sql+ 每张表独立的t1.sql.gz,天然支持并行rsync -
myloader导入时建议加--disable-binlog和--queries-per-transaction 50000,否则日志写爆、事务太小拖慢速度 - 注意:
mydumper不自动导出视图/存储过程,需额外加--triggers --routines


















