mysqldump卡在10%因innodb快照生成需全表扫描,千万级表易阻塞;load data慢因逐行插入+索引维护;mysqlimport是load封装但更危险;主从延迟需停写、并行复制、校验一致性。

mysqldump 导出时为什么卡在 10% 就不动了?
默认 mysqldump 对大表会启用 --single-transaction + --lock-tables=false,看似无锁,但 InnoDB 在事务快照生成阶段仍需扫描全表元数据、构建 MVCC 快照——千万级表可能卡住几小时,尤其遇到长事务或高并发写入。
实操建议:
- 加
--skip-opt --no-create-info --extended-insert=false:禁用自动优化、跳过建表语句、关闭多值 INSERT(避免单行超长触发缓冲区重分配) - 强制分片导出:用
--where="id BETWEEN 1 AND 1000000"拆成多个文件,每份控制在 500MB 以内 - 避开业务高峰执行,且确保
innodb_buffer_pool_size不低于物理内存的 70%,否则磁盘 IO 成瓶颈
LOAD DATA INFILE 导入慢到像爬?
直接跑 LOAD DATA INFILE 默认走逐行解析 + 单事务提交,对千万级数据等于执行一千万次 insert,还带唯一索引校验和二级索引维护,速度必然崩盘。
实操建议:
- 导入前先关索引:
ALTER TABLE t DISABLE KEYS(仅对 MyISAM 有效),InnoDB 必须改用SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; - 把
innodb_log_file_size调大到 1G+,innodb_log_buffer_size至少 32M,避免频繁刷 log - 用
LOAD DATA INFILE ... IGNORE或REPLACE替代普通 LOAD,减少冲突检测开销 - 文件必须放在 MySQL 服务端本地路径(如
/var/lib/mysql-files/),远程路径会退化成客户端读取+网络传输,速度掉 5 倍以上
用 mysqlimport 还是 LOAD DATA INFILE?
mysqlimport 是 LOAD DATA INFILE 的命令行封装,两者底层完全一致,但 mysqlimport 默认开启 --delete 和 --replace 等危险开关,且不支持自定义字段分隔符以外的复杂格式(比如嵌套 JSON 字段)。
实操建议:
- 纯 CSV 导入且字段简单:用
mysqlimport --local --fields-terminated-by=',' --lines-terminated-by='\n'更省事 - 含特殊字符、NULL 处理、时间格式转换:必须手写
LOAD DATA INFILE+SET子句,例如SET created_at = STR_TO_DATE(@created_at, '%Y-%m-%d %H:%i:%s') -
mysqlimport不会告诉你哪一行解析失败,错误日志只报“Got error …”,而LOAD DATA可配合SHOW WARNINGS定位具体行号
主从延迟爆表,怎么让从库不拖后腿?
迁移期间主库写入压力陡增,从库 SQL 线程单线程回放 binlog,极易堆积。常见现象是 Seconds_Behind_Master 持续 > 3600,甚至复制中断。
实操建议:
- 迁移前停写目标表,用
FLUSH TABLES WITH READ LOCK+SHOW MASTER STATUS记下位点,再解锁导出,保证主从起始一致 - 从库临时启用并行复制:
SET GLOBAL slave_parallel_type='LOGICAL_CLOCK'; SET GLOBAL slave_parallel_workers=8; - 导入完成后别急着启同步,先在从库
SELECT COUNT(*)校验行数,再用pt-table-checksum抽样比对数据一致性
真正麻烦的是外键约束和触发器——它们会让单条 INSERT 变成多表联动操作,导入时务必提前 DISABLE TRIGGERS 并确认外键是否真需要保留。很多迁移其实可以先去外键,等数据稳了再重建。











