extended-insert 是什么
mysqldump 默认开启 --extended-insert,把一张表的多行数据合并进一条 INSERT ... VALUES (...),(...),(...) 语句里。好处很直接:文件更小、恢复时每条语句提交更多行,导入速度快得多。代价是这条语句出错时整批回滚,坏行不好定位,也无法直接做文本 diff。需要逐行对比、定位坏行或做数据比对时,用 --skip-extended-insert 拆成一行一条 INSERT。
基本信息
| 默认行为 | --extended-insert 开启,多行合并为一条 INSERT |
|---|---|
| 关闭方式 | --skip-extended-insert,每行一条 INSERT |
| 单条大小控制 | --net-buffer-length 影响单条 INSERT 的字节上限,默认约 1MB |
| 恢复端约束 | 服务端 max_allowed_packet 必须大于备份文件里的单条语句 |
| 适用工具 | mysqldump / mysqlpump,MySQL 8.0 与 MariaDB 均默认开启 |
典型使用场景
- 快速恢复:常规全量备份与灾备演练保持默认批量插入,导入时间显著更短
- 配置表逐行对比:把配置数据拆成单行 INSERT 后用 diff 比对两个环境差异
- 定位坏行:批量插入因数据问题失败时,重导出为单行模式逐条执行,快速筛出问题记录
- 增量合并:只补充数据时配合 --no-create-info 与 --skip-triggers,避免动结构
- 网络受限环境:调小 --net-buffer-length 使单条语句变小,降低超时与丢包重传概率
两种模式对比
两种模式对比
# 默认批量插入:文件小、恢复快
mysqldump -uroot -p appdb orders > orders_extended.sql
grep -c 'INSERT INTO' orders_extended.sql # 语句条数很少
# 逐行插入:便于 diff 与定位坏行,文件明显更大
mysqldump -uroot -p --skip-extended-insert --skip-comments \
appdb config_table > config_rows.sql
grep -c 'INSERT INTO' config_rows.sql # 语句条数与行数接近
# 限制单条 INSERT 大小,避免恢复端 packet 限制
mysqldump -uroot -p --net-buffer-length=16384 appdb big_table > big.sql
# 恢复前先确认服务端允许的单包大小
mysql -uroot -p -e "SHOW VARIABLES LIKE 'max_allowed_packet';"模式选择对照
| 维度 | 默认(批量) | --skip-extended-insert(逐行) |
|---|---|---|
| 备份文件大小 | 小 | 明显更大 |
| 恢复速度 | 快 | 慢,语句解析次数多 |
| 坏行定位 | 差,整条语句一起失败 | 好,逐行执行即可定位 |
| 文本比对 | 不友好,一行含多记录 | 友好,一行一条记录 |
| 适用场景 | 常规备份、灾备演练 | 数据比对、故障排查 |
批量 INSERT 失败会整条语句回滚:错误信息只给出行号,无法直接知道是哪个值不合法。大表恢复报错的排查路径是先看 max_allowed_packet 是否偏小,再考虑重导为逐行模式定位。
--net-buffer-length 决定 mysqldump 攒多久写一条 INSERT,调小会让语句变多、文件变大、导入变慢,通常在需要绕开 packet 限制或网络不稳时才调。