亿级大表迁移不能依赖默认参数,必须按物理核心数调线程(-t设为1.2~1.5倍)、用-r分片、关闭时区转换、手动建库建表,否则易卡死或恢复失败。

直接上结论:亿级大表迁移不能靠默认 -t 4,必须按物理核心数调线程、用 -r 分片、关时区转换、手动建库建表,否则不是慢,而是卡死或恢复失败。
为什么 -t 4 在亿级表上反而更慢
默认 4 线程对 SSD + 16 核以上机器是严重资源浪费。实测 CPU 利用率长期压在 15%~20%,IO 也远未跑满。真正释放并发能力得主动调参:
-
-t值建议设为物理核心数的 1.2~1.5 倍(例如 12 核机器用-t 14),超过 24 后上下文切换开销反升 - 别盲目堆高线程数——若磁盘是 SATA 或网络带宽不足,
-t > 16可能引发 IOPS 争抢和连接超时 - 搭配
--long-query-guard 300和--kill-long-queries,防备份被长事务拖住
-r 行分片怎么设才不卡住大表扫描
不分片时,mydumper 对单表只起一个线程扫到底,亿级表可能跑几小时不动,其他线程干等。用 -r 强制按主键范围切块,让多个线程并行干活:
- 千万级表用
-r 1000000(100 万行/块)较稳 - 亿级表建议压到
-r 500000,避免单 chunk 扫描太久触发锁等待或超时 - 若表无主键或主键稀疏,
-r失效,改用--chunk-filesize 50按 50MB 切文件(防单文件超 2GB 导致 OOM) - 注意:启用
-r后,--chunk-filesize会自动禁用,二者互斥
导入前必须手动做的三件事
myloader 不建库、不建表、不关外键——它只认目录结构和 SQL 文件。跳过这步,90% 的报错都源于此:
- 先执行
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS target_db" - 再用
cat ./export-20260904/metadata | grep "CREATE TABLE" | mysql -u root -p target_db或直接跑mydumper --no-data单独导出 schema - 导入前连进目标库执行
SET FOREIGN_KEY_CHECKS=0;,否则遇到外键约束直接卡住或报Cannot add or update a child row - 确认目标库
max_allowed_packet≥ 256M,否则大 BLOB 字段导入时会截断,报错类似MySQL server has gone away
容易被忽略的 consistency 和时区坑
亿级备份耗时长,metadata 里记录的 binlog pos 是**开始时刻**,不是结束时刻。若备份跑了 8 分钟,这个位点已滞后,做 PITR 时不准;而时区转换则悄悄污染 datetime 字段:
- 加
--skip-tz-utc,避免每条 INSERT 都套CONVERT_TZ(),小表提速 20%,大表可省下几十分钟 - 别依赖
--no-locks做“无锁”迁移——MyISAM 表仍会被加读锁,InnoDB 表虽用快照,但跨库视图、存储过程等非事务对象不保证原子性 - 若源库有跨库引用(如视图查
db2.table_x),必须单独用mysqldump -d -n -t db2 view_name导出,mydumper不处理这类依赖











