如何处理mysqldump创建的巨大行长度

pav*_*ium 59 mysql mysqldump

我在cron作业中使用mysqldump来备份超过200万行的数据库.

它创建一个文本文件,可用于从命令行恢复数据记录.

我认为在恢复之前编辑转储作为一种更改值和表或列名称的快速方法会很有用- 至少在我了解更多信息并对使用ALTER和UPDATE执行此操作充满信心之前.

编辑大型文本文件并不会让我感到烦恼,但我惊讶地发现,在250兆字节的数据库转储中,只有大约300行.每行都有800k字符长.

是否有另一种生成转储的方法,可以更好地控制线路长度?

或者我应该使用sed或Perl等工具对转储进行后处理?

Vot*_*ple 73

默认情况下,每个表mysqldump只生成一个INSERT命令,从而为每个被转储的生成一行(非常长)的插入数据.这主要是因为"批处理"插入比INSERT为每个表中的每个记录生成单独的查询要快得多.

所以,它不是mysqldump创造了任意长线,而你可以强加一些其他的截止长度.线条很长是有原因的.

如果将INSERTs分解为多行是非常重要的,您可以通过以下方式指出:

mysqldump --extended-insert=FALSE --complete-insert=TRUE ...
Run Code Online (Sandbox Code Playgroud)

但请注意,以此格式恢复表将花费更长时间.

  • @VoteyDisciple - 这解释了为什么它是一个很大的`INSERT`,但不是为什么它是一个大线.每个插入行后很容易有换行符,对吗? (24认同)
  • 在我看来,这只是一个"格式问题".为什么不生成ONE INSERT语句,但是在单独的行中每行的值块.这将使生成的文件成为可读的,并且根本不会影响性能. (13认同)
  • 哦,确实有需求!我们使用mysqldump为每个"标签"存储DB.我们在标签之间进行了一些较小的更新,并且使用一条大线您无法看到哪些内容已更改,您需要侧向滚动到它. (9认同)
  • 我想知道是否有人可以确认 net_buffer_length 选项也能正常工作。这对我来说似乎是一个更好的解决方案。 (2认同)
  • PHPMyAdmin 生成其转储文件,每次插入之间都有一个新行。我猜有这样的需求。 (2认同)

小智 31

我正在浏览MySQL源代码,寻找今天这个问题的解决方案.最大行长度由变量opt_net_buffer_length强制执行,该变量应该与MySQL服务器的缓冲区大小相匹配.它很滑稽.

但无论如何,它是一个选项,所以只需这样做:

mysqldump --net_buffer_length=5000 ...
Run Code Online (Sandbox Code Playgroud)

最小值为4096.

  • 这会导致包含超过4K数据的单个行出现问题吗? (7认同)

Sta*_*ode 18

我在MySQL论坛上遇到了一个答案,最终确定在单独使用mysqldump后无法在每个INSERT组之后添加'\n',而不修改源:

根据逗号或括号,不能100%正确解析扩展格式,您可以计算字段.最好的解决方案,将mysqldump修复为输出上的换行符.

非常小的更改:在第3506行,您可以看到输出行结尾逗号的位置:
fputc(',',md_result_file); /* Always row break */

只需在第3506行后立即插入此行:
fputc('\n',md_result_file); /* Lon Binder says wrap that line! */

重新编译完成.

@see http://forums.mysql.com/read.php?28,420002,426110#msg-426110

谢谢Lon B!

(我已经包含了MySQL论坛中的内容,以防论坛消失.)

  • 呃,为什么这不是mysqldump的选项?这是两全其美的. (15认同)

seb*_*ien 5

使用正则表达式分割行是不够的,您需要一个能够正确理解引号和转义字符的解析器。

我刚刚写了一个解析器,因为我找不到一个:http : //blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts.html


Nic*_*sai 5

该标志也起作用:

mysqldump --skip-extended-insert 
Run Code Online (Sandbox Code Playgroud)

与相同--extended-insert=FALSE