真正可控的mysql迁移限速方式是控制写入节奏和并发粒度:用--single-transaction与--skip-triggers减锁开销,按表分批导出,配合pv限速导入,调低innodb_flush_log_at_trx_commit和sync_binlog(迁移后须恢复),优先选用mysqlpump并行导出或xtrabackup分阶段限速,全程需用iostat监控io负载。

MySQL 迁移时磁盘 IO 打满,mysqldump 直接卡死怎么办
直接限制 mysqldump 的 IO 是无效的——它本身不提供限速参数,靠系统级工具(如 ionice、cpulimit)压制效果差,还容易导致超时或连接中断。真正可控的方式是控制写入节奏和并发粒度。
- 用
--single-transaction+--skip-triggers减少锁和触发器开销,避免长事务拖慢 IO 队列 - 按表分批导出:
mysqldump -t --no-create-info db_name table1 > t1.sql,再用pv -L 5m | mysql db_name控制导入速率 - 禁用
innodb_flush_log_at_trx_commit=2和sync_binlog=0(仅限迁移机,完事后必须改回)
mysqlpump 比 mysqldump 更适合限速迁移吗
是,但不是因为“自带限速”,而是它支持并行导出 + 表级粒度控制,更容易配合外部限速工具生效。不过要注意 MySQL 版本兼容性:5.7.8+ 才有 mysqlpump,且不支持视图定义导出(会报错 Unknown error)。
- 用
--default-parallelism=2控制并发线程数,避免多表同时刷盘 - 配合
ionice -c2 -n7降低 IO 调度优先级,比cpulimit对磁盘更友好 - 导出大表时加
--where="id BETWEEN 1 AND 100000"分片,再拼接 SQL,比单次全量更稳
用 pt-archiver 做在线限速迁移的硬约束条件
pt-archiver 不是为全库迁移设计的,它本质是“逐行归档”,IO 压力小但耗时极长;只有在目标库可写、源库允许长连接、且能接受小时级迁移时才适用。误用会导致主从延迟飙升甚至 Deadlock found when trying to get lock。
- 必须加
--limit 1000 --sleep 0.1控制每批处理量和间隔,否则默认无节制刷盘 -
--bulk-insert可提升导入效率,但会放大单次 IO 写入峰值,需配合--txn-size 100降频 - 不能用于含
JSON字段或生成列的表(会报Invalid JSON text),需提前检查表结构
物理迁移(xtrabackup)如何避开 IO 瓶颈
xtrabackup 备份阶段本身就会打满磁盘 IO,但它的优势在于“备份后限速”——压缩、拷贝、解压三个环节都可独立限速,比逻辑迁移更可控。
- 备份时加
--compress --compress-threads=1,避免多线程压缩抢 IO - 拷贝到目标机用
rsync --bwlimit=10000(单位 KB/s),比scp更稳定 - 恢复前先
innobackupex --apply-log --use-memory=2G /path,内存不足会退化成磁盘排序,IO 翻倍
iostat -x 1 得开着看 %util 和 await,而不是只盯着迁移命令跑没跑完。











