Ken*_*ett 46 mysql mysqldump mysqladministrator mysql-workbench
这已被问过几次,但我无法找到解决问题的方法.基本上当使用mysqldump(MySQL Workbench管理工具的内置工具)时,当我使用扩展插入转储数据库时,我会获得大量的长行数据.我明白为什么会这样做,因为它通过将数据作为一个命令(特别是在InnoDB上)插入来加速插入,但格式化使得真正难以实际查看转储文件中的数据,或者使用diff工具比较两个文件如果你将它们存储在版本控制等等.在我的情况下,我将它们存储在版本控制中,因为我们使用转储文件来跟踪我们的集成测试数据库.
现在我知道我可以关闭扩展插入,所以每行会有一个插入,这是有效的,但是每次使用转储文件进行恢复时它都会变慢.
我的核心问题是,在我转储文件时我们曾经使用过的OLD工具(MySQL管理员),它基本上做了同样的事情,但是它的格式是INSERT语句每行放一个插入,同时仍然进行批量插入.所以不是这样的:
INSERT INTO `coupon_gv_customer` (`customer_id`,`amount`) VALUES (887,'0.0000'),191607,'1.0300');
Run Code Online (Sandbox Code Playgroud)
你得到这个:
INSERT INTO `coupon_gv_customer` (`customer_id`,`amount`) VALUES
(887,'0.0000'),
(191607,'1.0300');
Run Code Online (Sandbox Code Playgroud)
无论我尝试什么选项,似乎没有任何方法可以获得这样的转储,这真的是两全其美.是的,它需要更多的空间,但在需要人来阅读文件的情况下,它会使它变得更有用.
我错过了什么,有一种方法可以使用MySQLDump,或者我们都倒退了,旧的(现已弃用的)MySQL管理员工具中的这个功能不再可用?
小智 34
请尝试使用以下选项: - skip-extended-insert
它对我有用.
小智 30
使用默认的mysqldump格式,转储的每个记录将在转储文件(即sql文件)中生成单独的INSERT命令,每个命令都在其自己的行上.这对于源控制(例如,svn,git等)是完美的,因为它使得diff和delta分辨率更精细,并且最终导致更有效的源控制过程.但是,对于大小合适的表,执行所有这些INSERT查询可能会使得从sql文件恢复过于缓慢.
使用--extended-insert选项通过将所有记录包装到转储的sql文件中的单行上的单个INSERT命令来修复多个INSERT问题.但是,源控制过程变得非常低效.整个表内容在sql文件中的一行中表示,如果单个字符在该表中的任何位置发生更改,源控件将标记整个行(即整个表)作为版本之间的差异.而且,对于大型表,这否定了使用正式源控制系统的许多好处.
理想情况下,为了有效地恢复数据库,在sql文件中,我们希望每个表都由一个INSERT表示.对于有效的源控制过程,在sql文件中,我们希望该INSERT命令中的每条记录都驻留在它自己的行上.
我的解决方案是以下备份脚本:
#!/bin/bash
cd my_git_directory/
ARGS="--host=myhostname --user=myusername --password=mypassword --opt --skip-dump-date"
/usr/bin/mysqldump $ARGS --database mydatabase | sed 's$VALUES ($VALUES\n($g' | sed 's$),($),\n($g' > mydatabase.sql
git fetch origin master
git merge origin/master
git add mydatabase.sql
git commit -m "Daily backup."
git push origin master
Run Code Online (Sandbox Code Playgroud)
结果是一个sql文件INSERT命令格式,如下所示:
INSERT INTO `mytable` VALUES
(r1c1value, r1c2value, r1c3value),
(r2c1value, r2c2value, r2c3value),
(r3c1value, r3c2value, r3c3value);
Run Code Online (Sandbox Code Playgroud)
一些说明:
小智 11
正如其他人所说使用sed替换"),"(因为它可以作为数据库中的内容出现而不安全.但是有一种方法可以做到这一点:如果您的数据库名称是my_database,则运行以下命令:
$ mysqldump -u my_db_user -p -h 127.0.0.1 --skip-extended-insert my_database > my_database.sql
$ sed ':a;N;$!ba;s/)\;\nINSERT INTO `[A-Za-z0-9$_]*` VALUES /),\n/g' my_database.sql > my_database2.sql
Run Code Online (Sandbox Code Playgroud)
你也可以使用"sed -i"来替换内联.
以下是此代码正在执行的操作:
希望这可以帮助
使用--tab
像这样的选项将转储存储到带有mysqldump的CSV文件中怎么样?
mysqldump --tab=/path/to/serverlocaldir --single-transaction <database> table_a
Run Code Online (Sandbox Code Playgroud)
这会产生两个文件:
table_a.sql
只包含表create语句; 和table_a.txt
包含制表符分隔的数据.您可以通过LOAD DATA
以下方式恢复您的表
LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt'
INTO TABLE table_a FIELDS TERMINATED BY '\t' ...
Run Code Online (Sandbox Code Playgroud)
LOAD DATA通常比使用INSERT语句快20倍.
如果必须将数据恢复到另一个表中(例如,为了审查或测试目的),您可以创建一个"镜像"表:
CREATE TABLE table_for_test LIKE table_a;
Run Code Online (Sandbox Code Playgroud)
然后将CSV加载到新表中:
LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt'
INTO TABLE table_for_test FIELDS TERMINATED BY '\t' ...
Run Code Online (Sandbox Code Playgroud)
CSV文件是简单的diff文件或里面找,或对非SQL技术的用户谁可以使用常见的工具,如Excel
,Access
或命令行(diff
,comm
,等...)
我担心这是不可能的.在旧的MySQL管理员中,我编写了用于转储db对象的代码,该代码完全独立于mysqldump工具,因此提供了许多其他选项(如此格式化或进度反馈).在MySQL Workbench中,决定使用mysqldump工具,除了在某些方面倒退并产生版本问题之外,还有一个优点是始终保持与服务器的最新状态.
所以简短的回答是:mysqldump目前无法进行格式化.