如何在MySQL转储中摆脱这些注释?


80

我正在尝试创建数据库的仅转储的简单结构。使用mysqldump给我一个类似的结果:

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

DROP TABLE IF EXISTS `foo`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;

无论我尝试什么,我似乎都无法摆脱这些评论。

我目前正在使用: mysqldump -p -d --add-drop-table --skip-tz-utc --skip-set-charset -h 127.0.0.1 -u foo bar --result-file=dumpfile.sql

编辑:但是,我确实希望保留其他评论,例如-- MySQL dump 10.13 Distrib 5.1.41, for Win32 (ia32)


不是一个直接的答案-但我已经完全放弃了mysqldump,完全是为了mk-parallel-dump-它更快(产生多个进程),并且取决于您对转储输出的处理方式,因此更加灵活,因为它有效地封装了mysqldump和'select一起成为outfile的语法。
zznate

1
我想知道为什么Oracle没有在mysqdump中添加如此重要的选项吗?
PHPst 2015年

Answers:


160

哇!即使看起来是这样,这些也不是真正的评论。它们是条件执行令牌。

采取这一行:

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

如果mySQL的版本为4.00.14或更高版本,则MySQL服务器将运行此语句。

该魔术注释语法记录在手册的“注释语法”部分。

您可能不想摆脱这些东西。


2
这明确要求有关意见的另一个问题在MySQL被视为可执行的SQL(刚刚发布了由我):stackoverflow.com/questions/25614919/...
丹尼森鲍姆

1
在某些情况下,删除注释会有所帮助。即bugs.mysql.com/bug.php?id=48972,因为--insert-ignore由于它们而无法按预期工作时
varela 2015年

+1我从不知道。我以为它们只是mysql dump在导出时正在运行的命令。很有启发性的答案。
Captain Hypertext

假设这意味着应该有预期的兼容性选项,该选项指定您是否希望在较早的mysql版本上运行sql,如果不希望运行,则需要将其包装在条件注释中。
CMCDragonkai '17年

39

我知道这是一个古老的问题,但这至少是一个答案。我也找不到mysqldump中的标记来删除条件注释,或者确实没有更好的选择来设置最低mysql版本以使这些注释出现。如果只想对它们全部进行核对,则可以使用grep或sed(sed留空行,grep不会)来做到这一点:

mysqldump ... | grep -v '^\/\*![0-9]\{5\}.*\/;$'
mysqldump ... | sed -e 's/^\/\*![0-9]\{5\}.*\/;$//g'

要满足我自己的有条件删除依赖于mysql版本的注释的愿望,请使用以下命令之一(删除<mysql5的所有注释):

mysqldump ... | grep -v '^\/\*![0-4][0-9]\{4\}.*\/;$'
mysqldump ... | sed -e 's/^\/\*![0-4][0-9]\{4\}.*\/;$//g'

1
对于rsnapshot备份,删除最后一行非常有用,因此,未更改结果的数据库在同一文件中:mysqldump ... | grep -v '^-- Dump completed on .*$'
rubo77

是的,但问题是您可能会失去DROP DATABASE IF EXISTS OR IGNORING YOUR CURRENT SESSION VARIABLES 。除非您知道自己在做什么,否则:尤其是在环境/主机之间迁移时,请不要将其删除。由于多种原因,结果输出可能与预期不符。他们被放在那里保护你。但是如果您不想系上安全带,那是您的选择。
JayRizzo

1
@ rubo77您也可以使用此mysql dump参数:--skip-dump-date
dehart

33

试试--skip-comments

谢谢

编辑:

我明白了。尝试这个

--skip-add-drop-table --skip-add-locks --skip-disable-keys --skip-set-charset

试着删除一些选项,直到获得所需的结果,基本上这与--compact没有--skip-comments

--skip-comments 删除有关版本和内容的评论。


5
不幸的是,这删除了我想要的所有注释,而所有我不想要的注释都保留了下来。
etheros

我同意@etheros,但我们应该详细说明。我的用例涉及源代码控制的结构数据。我不想每张桌子都没有不必要的chat不休。我喜欢SET NAMES调用--skip-set-charset,如建议在这个答案,排除; 它在转储文件的开头仅发生一次,并且可能以实质性的方式影响数据恢复。我喜欢--skip-add-locks --skip-disable-keys我的用例。但是,某些条件注释(例如/*!40101 SET character_set_client = @saved_cs_client */;/*!40101 SET character_set_client = utf8 */...)是否有用?
本·约翰逊

1
@BenJohnson不,他们不是。character_set_client由于错误或其他原因,无法在5.6中进行设置,因此当您在mysqldumping中转储示例utf8mb4数据时,会在不希望使用它们的地方得到这些条件注释。
斯拉瓦


12

从技术上讲,您要摆脱的行不是注释。它们在开始时临时修改了一些变量,然后在结束时将它们重置为先前的值。

由于您使用的是--no-data,它们在您的情况下不是很有用(但它们也无害),但我认为值得一提的是,这些行确实是有目的的,而不仅仅是注释。


4

这些不是注释,脚本那部分的执行取决于您的mysql版本。

您可以删除“评论部分”,例如

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */

SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0

使脚本阅读更“舒适”。

如果您尝试在比“注释”中指定的版本更高的版本中运行“舒适”脚本,则会收到错误消息。


2
我们如何“删除评论部分”?是否有转储选项?我不想手工处理几个演出文件。
mpen 2015年

实际上应该是:如果尝试在比“注释”中指定的版本更旧的版本中运行“舒适”脚本,则会收到错误消息。
丹尼尔(Daniel)

0

可能在其上运行正则表达式以删除包含40014或40111等的行。


0

由于您使用的是Windows,因此如果没有人找到更好的解决方案,则可以使用Python脚本代替:

import re, sys
sql = sys.stdin.read()
regex = re.compile(r'/\*![^\n]* \*/;\n', re.M)
print regex.sub('', sql)

从命令行使用:

python program.py < your.sql > output.sql

它删除所有这样的行:

/*!....... */;

0

如果您在尝试将struct / sql文件包含在git / github中时偶然发现了这个答案,则可以在耙db:structure:dump之后立即使用以下代码删除自动增量

# Remove beginning auto increments to prevent merge conflicts
filename = 'db/structure.sql'
File.atomic_write(filename) do |output|
  File.open(filename, 'rb').each do |input|
    output.write(input.gsub(/\s+AUTO_INCREMENT=\d+\s+/, ' '))
  end
end

1
用“用正则表达式分隔行”答案上的所有否决票是什么?这些是完全有效的。这一点特别适用于我的情况。所有人的+1。
plainjimbo 2014年


0

使用 --dump-date=FALSE

确实执行OP的要求。(不完全是,我明白了)

资料来源:mysqldump选项摘要

编辑:一分钟后,我意识到,这不是在寻找的OP,而是留在这里...希望有人可以使用它:这个日期行破坏了源代码管理,因为它总是一个更改...


1
正是我在寻找什么,为什么人们甚至对此表示反对?来自我的大力支持。
kungfooman

0

保留条件执行注释非常重要。但是,如果您完全知道将加载转储的MySQL版本大于或等于创建转储版本的MySQL版本,则可以使用以下命令删除“ comment”部分:

sed -r  s'#/\*![0-9]{5} ?([^*]*)\*/#\1#'g

它将转换诸如

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;

SET SQL_MODE=@OLD_SQL_MODE ;

因为此行必须在任何MySQL> = 4.1.1上运行

请注意,这不会删除多行条件执行注释,例如在转储触发器时。

由于无法预测未来,因此最好将转储带有评论的内容存储起来,并仅在您希望对其进行可视化时将其删除。

mysqldump ... > dump.sql
cat dump.sql | sed -E  s'#/\*![0-9]{5} ?([^*]*)\*/#\1#'g > dump.no-comments.sql

-1

正如@Ollie和其他一些人指出的那样,这些是以注释样式编写的条件执行令牌,但有一定目的。没有它们,您可能会遇到重新创建具有严格执行的外键约束的表的问题。例如,表A具有用于表B的FK,因此,直到表B可以创建表A,依此类推。如果不禁用键检查,则可能永远无法重新创建它们,具体取决于表顺序的罚款方式。


-2

我不知道这是否是您要寻找的东西,我只是想摆脱所有mysql注释内容,以便能够使用语法突出显示框,我使用了一个简单的正则表达式,并用以下“ / \ *![ 0-9] {5} | \ * /“和瞧!代码中漂亮的颜色;)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.